{"id":53,"date":"2023-02-10T02:08:41","date_gmt":"2023-02-10T02:08:41","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/melsbyg\/?p=53"},"modified":"2023-02-10T02:08:41","modified_gmt":"2023-02-10T02:08:41","slug":"a-couple-neat-c-features","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/melsbyg\/2023\/02\/10\/a-couple-neat-c-features\/","title":{"rendered":"A Couple Neat C# Features"},"content":{"rendered":"\n<p>Picking up any new programming language takes some time. Each language, no matter how similar to others, has its own idiosyncrasies and idioms. The process of learning a new language often is eased by having a background in other languages. By finding similarities and differences, the particularities of the new language are more easily understood. Furthermore, learning a new language can change the way one thinks about problem-solving while programming. I definitely thought more about the advantages and tradeoffs of the functional programming paradigm while learning some <a rel=\"noreferrer noopener\" href=\"https:\/\/www.haskell.org\/\" data-type=\"URL\" data-id=\"https:\/\/www.haskell.org\/\" target=\"_blank\">Haskell<\/a> recently. The lessons I learned can be applied in a different language like Javascript. C# was not wildly out of my comfort zone, as I have prior Java and C++ experience. However, there were a few surprises and neat features that I really appreciate in a programming language. Here are some of the highlights of C# that I encountered working with it this term.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Async\/Await, Tasks, and Static Typing<\/h3>\n\n\n\n<p>I imagine the programming language that first comes to mind for the majority of programmers who hear &#8220;<code>async<\/code>\/<code>await<\/code>&#8221; is Javascript, simply due to its immense popularity. However, Javascript introduced these keywords in 2017, far after C#, which introduced them in <a rel=\"noreferrer noopener\" href=\"https:\/\/softwareengineering.stackexchange.com\/questions\/377464\/who-did-async-await-first\" data-type=\"URL\" data-id=\"https:\/\/softwareengineering.stackexchange.com\/questions\/377464\/who-did-async-await-first\" target=\"_blank\">2012<\/a>. These two keywords make it easier to program using asynchronous tasks, which C# represents using the <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.threading.tasks.task?view=net-7.0\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.threading.tasks.task?view=net-7.0\">Task class<\/a>. A <code>Task<\/code> in C# is somewhat analogous to a <code>Promise<\/code> in Javascript&#8211;both represent processes that can be executed asynchronously and have completion statuses. <\/p>\n\n\n\n<p>One advantage of programming using Tasks in C# over Promises in Javascript is brought out by another feature of C#: its use of <a rel=\"noreferrer noopener\" href=\"https:\/\/stackoverflow.com\/questions\/859186\/why-is-c-sharp-statically-typed\" data-type=\"URL\" data-id=\"https:\/\/stackoverflow.com\/questions\/859186\/why-is-c-sharp-statically-typed\" target=\"_blank\">static typing<\/a> and <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/types\/generics\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/types\/generics\" target=\"_blank\">generics<\/a>. Static typing provides signposts and guardrails for what a Task will eventually resolve to. Because Javascript is not statically typed and there are no required type signatures on functions, an async Javascript function could resolve to anything! This ambiguity, combined with the additional complexity of asynchronous design, sometimes causes issues for me in Javascript. However, C# has a <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.threading.tasks.task-1?view=net-7.0\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.threading.tasks.task-1?view=net-7.0\" target=\"_blank\">Task&lt;TResult&gt;<\/a> class that makes apparent what type the eventual task result will be. To illustrate, take a look at <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/async\/\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/async\/\" target=\"_blank\">this example from the Microsoft docs<\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"166\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-6.54.27-PM.png\" alt=\"\" class=\"wp-image-54\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-6.54.27-PM.png 646w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-6.54.27-PM-300x77.png 300w\" sizes=\"auto, (max-width: 646px) 100vw, 646px\" \/><\/figure>\n\n\n\n<p>We know the <code>Task<\/code> that is returned from the call to <code>FryEggsAsync(2)<\/code> will resolve to an object of type <code>Egg<\/code>. Then when we await the task, we can be sure that the type of the object we are awaiting is <code>Egg<\/code>. Because <code>TResult<\/code> in <code>Task&lt;TResult&gt;<\/code> is just a type parameter, we can specify which types of objects our asynchronous functions will eventually return and what our Tasks will eventually resolve to. Here is another great example from the same docs:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"170\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-6.43.09-PM.png\" alt=\"\" class=\"wp-image-55\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-6.43.09-PM.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-6.43.09-PM-300x66.png 300w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p>We can be certain that <code>eggsTask<\/code> will resolve to an <code>Egg<\/code>, <code>baconTask<\/code> will resolve to a <code>Bacon<\/code>, and <code>toastTask<\/code> will resolve to a <code>Toast<\/code>. This certainty is an extension of the static typing present in C#, and it is exceptionally useful within the confusing context of asynchronous programming. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LINQ<\/h3>\n\n\n\n<p>One neat feature I encountered in C# that I haven&#8217;t encountered anywhere else is the integration of a multipurpose query language into C# itself. This query language can be used to get query results from <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/linq-and-strings\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/linq-and-strings\" target=\"_blank\">Strings<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/linq-and-file-directories\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/linq-and-file-directories\" target=\"_blank\">File Structures<\/a>, Data Structures that implement the IEnumerable interface such as <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/how-to-query-an-arraylist-with-linq\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/how-to-query-an-arraylist-with-linq\" target=\"_blank\">ArrayLists<\/a>, and <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/ef\/core\/querying\/\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/ef\/core\/querying\/\" target=\"_blank\">even SQL databases<\/a>! I only have been working with C# for a month or so, but I imagine an experienced C# developer would really appreciate having a unified way to query all these sources. The syntax is simple and reminiscent of SQL. Below is <a rel=\"noreferrer noopener\" href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/\" target=\"_blank\">an example from the Microsoft docs<\/a> illustrating a simple query.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"874\" height=\"660\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-7.12.43-PM-1.png\" alt=\"\" class=\"wp-image-57\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-7.12.43-PM-1.png 874w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-7.12.43-PM-1-300x227.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/6488\/files\/2023\/02\/Screenshot-2023-02-09-at-7.12.43-PM-1-768x580.png 768w\" sizes=\"auto, (max-width: 874px) 100vw, 874px\" \/><\/figure>\n\n\n\n<p>Note that the variable <code>scoreQuery<\/code> gets its value assigned by the programmer instructing the program about the criteria necessary for a score to be included in <code>scoreQuery<\/code> instead of directly telling the program how to loop through scores. For contrast, the same result can be achieved by looping through scores with a <code>foreach<\/code> statement and writing to console <code>if score &gt; 80<\/code>. <\/p>\n\n\n\n<p>These contrasting ways of approaching the problem illustrate the difference between two different types of programming: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.freecodecamp.org\/news\/imperative-vs-declarative-programming-difference\/\" data-type=\"URL\" data-id=\"https:\/\/www.freecodecamp.org\/news\/imperative-vs-declarative-programming-difference\/\" target=\"_blank\">imperative and declarative<\/a>. Imperative programming involves the writing of step-by-step instructions that will result in the desired result. An imperative way to approach the problem above would be to write a <code>for<\/code> or <code>foreach<\/code> loop and specify what should be done at each step of the loop. A declarative way to approach the problem would be to simply lay out a set of expectations for <code>scoreQuery<\/code> using a query language and letting the compiler figure out how exactly to meet those expectations. Most common programming languages are able to accommodate both paradigms to some extent. Python has declarative <a href=\"https:\/\/docs.python.org\/3\/tutorial\/datastructures.html#list-comprehensions\" data-type=\"URL\" data-id=\"https:\/\/docs.python.org\/3\/tutorial\/datastructures.html#list-comprehensions\" target=\"_blank\" rel=\"noreferrer noopener\">list comprehensions<\/a>, and Javascript has the declarative <code><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/map\" data-type=\"URL\" data-id=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/map\" target=\"_blank\" rel=\"noreferrer noopener\">map<\/a><\/code> and <code><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/filter\" data-type=\"URL\" data-id=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/filter\" target=\"_blank\" rel=\"noreferrer noopener\">filter<\/a><\/code> functions. However, LINQ is a neat design choice in C# because it aims to standardize the way imperative, query-like code is written. What&#8217;s so exciting about LINQ is that it&#8217;s not just for lists but for all sorts of instances where writing a query would be useful.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p>Programming in a new language is a learning experience, but not just for the language one is currently using. Thinking about language design choices helps one become a better programmer in many ways. Knowing what tool is right for which kind of job is a sign of being experienced in a craft. Considering the advantages and limitations of a language helps one think about how to approach problems. Trying out a different paradigm and taking away its lessons can change how one writes code in other languages too. Utilizing C# has been a fun experience, and I am always astounded by the ingenuity that goes into designing a programming language.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Picking up any new programming language takes some time. Each language, no matter how similar to others, has its own idiosyncrasies and idioms. The process of learning a new language often is eased by having a background in other languages. By finding similarities and differences, the particularities of the new language are more easily understood. [&hellip;]<\/p>\n","protected":false},"author":13173,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-53","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/users\/13173"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":1,"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"predecessor-version":[{"id":58,"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/posts\/53\/revisions\/58"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/melsbyg\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}