C# from an ActionScript/JavaScript Developer’s Perspective

Datetime:2016-08-23 02:53:59          Topic: C#  JavaScript  ActionScript           Share

Initially, gskinner was a shop with expertise in Flash/ActionScript technologies, and then JavaScript/HTML/CSS since the slow decline of Flash. However, in the past year we spent a great deal of time working with C# and XAML, specifically on the Windows 8/8.1 and Windows Phone 8/8.1 platforms.

I’m not going to dive into the super technical aspects of C#, since there are a plenty of resources available for that (See thelinks below to learn more). This is more of an overview of some experiences with working in a new technology stack; A brief description of differences in core concepts, language features, and a comparison of development tools.

To start off, lets jump into…

Strong Typing

Coming from an ActionScript and JavaScript background, the typing in C# was definitely a change from the relative “looseness” of the previous two (especially JavaScript). AS3 was a middle ground between dynamic and strong typing, where you had to ability to specify type, but it could still be optional. However, typing is strictly enforced in C#, which felt a little jarring given our last few years in JavaScript. Everything in C# requires a type (with the exception of objects using the “dynamic” keyword, but use of this modifier should be avoided at all costs, since it negates any advantages you receive with strong typing).

We had to keep types in mind when creating our objects. For example, here is something we normally use to create a lookup in JS

var hash = {};
hash[“key”] = “value”;

A generic object is created, then key value pairs are stored.

However, in C#, we use a specific Dictionary typed object

Dictionary<string, string> hash = new Dictionary<string, string>();
hash[“key”] = “value”;

We have to specify the types of both the key and value beforehand. In JS, we could associate keys with any type of value, even mixed types (not necessarily the best practice, but possible in the language). A compromise of sorts is found in AS3, where we have a typed object, but untyped keys and values.

Implicit typing was a neat feature that we used throughout, since the IDE did a nice job of showing you what each object’s type was when you hover over it. It’s a minor thing, but it saved us from typing too much over the course of a long project. So, the previous example could be written as

var hash = new Dictionary<string, string>();

Method Types

Due to the strict typing, we found there are many more types available in C# than what is in JS or AS3. For example, even passing a method reference was not as simple as we what we were used to. There are multiple types used for methods: actions, func, and delegates; each with their own uses.

An action type describes a method with no return type:

void DoStuff() {...}
void DoStuffWithParam(string param) {...}
Action MyAction = DoStuff;
Action MyActionWithParam = DoStuffWithParam;
MyAction(); //same as calling DoStuff()
MyActionWithParam(“foo”); //same as calling DoStuffWithParam(“foo”)

A func type describes a method with a return type:

string DoStuffAndReturnString() {...}
string ParseParam(int param) {...}
Func MyFunc = DoStuffAndReturnString;
Func MyFuncParam<int, string> = ParseParam; //the return type is specified last
var myString = MyFunc(); //same as calling DoStuffAndReturnString()
var myString2 = MyFuncParam(3); //same as calling ParseParam(3)

A delegate is a type placeholder for a method, and can be used as a stand-in for different methods (similar to a single method interface, but differences are explained here ). Delegates are the basis for Events in the framework.

delegate string MyDelegate(int param);
string MyMethod1(int p) {...}
string MyMethod2(int p) {...}
MyDelegate M1 = MyMethod1;
MyDelegate M2 = MyMethod2;
var myString = M1(1); //same as calling MyMethod1(1)
var myString2 = M2(1); //same as calling MyMethod2(1)

Lambda functions, or arrow functions as they will be known in ECMAScript 6, are more or less anonymous functions in shorthand. There are technical differences, explained here , here , and here . So the previous example can be written as:

delegate string MyDelegate(int param);
MyDelegate M1 = (param) => {...} //declare method body inline
MyDelegate M2 = (param) => {...} //declare method body inline
var myString = M1(1);
var myString2 = M2(1);

All of these different approaches for dealing with method types may seem very similar, but there are technical distinctions which are better explained in the following articles:

Overview of Delegates, Actions, Funcs, Lambdas

Creating delegates manually vs using existing method types

Creating delegates manually vs using existing method types 2

Collections

In addition to method types, there are also various collection types available. In JS and AS3, arrays can be resized via push() / pop() and shift() / unshift() methods. However, in C#, this behavior is found on typed lists instead. Lists are similar to AS3’s Vectors, where each element has to be of the same type. Arrays in C# are also typed, as well as expected to be of fixed size.

The use of collections should be familiar to those who used Flex, which has similar types such as ArrayCollection. However, the advantage that C# has over AS3 when dealing with queries is…

LINQ

LINQ (Language-Integrated Query) is built-in support in C# for querying elements in a dataset. Similar to SQL, we can specify a query used to filter a set of elements from anything that implements IEnumerable (which typed Lists in C# do). For example, lets say we want to get the first person named “Bob” in a large collection of people. Rather than looping through an array like in JS, we can just filter using the following syntax:

List<Person> People = GetAllPersons(); //populate the collection
var PersonQuery = from Person in People where Person.FirstName == "Bob" select Person;
var FirstBob = PersonQuery.First(); //the first "Bob"

Also, this can further be simplified using a Lambda function

var FirstBob = People.Where((person) => person.FirstName == "Bob").First();

This is opposed to:

var firstBob;
for (var person in people) {
     if (person.firstName == “Bob”) {
          firstBob = person; break;
     }
}

Overloading

Dealing with numerous method types was annoying at first. However, this was alleviated through the use of overloaded methods, which was another feature we have lived without for too long. Method overloading allowed us to specify different signatures for the same method, so we could pass in different types of parameters, and/or different number of arguments, and specifically handle each using a different function. There were a few times where we sorely missed this language feature when switching back to JS.

void DoStuffWithParam(string param) { … }
void DoStuffWithParam(string param, int param2) { … }
void DoStuffWithParam(int param) { … }
void DoStuffWithParam(int param, int param2) { … }

In short, we had to make minor adjustments to our coding approach to accommodate type enforcement to take full advantage of the available language tools.There are a lot of options available to us in the toolset we’re given to solve various problems. With that, let’s move onto the other half of C#/XAML …

Layout with XAML

Layout in Windows apps uses XAML, a markup language – so we found ourselves often comparing it to Flex’s MXML. Both can be used to layout the visual components of an app, either incode, or using awysiwyg-style editor. XAML is often accompanied by a C# file (the .cs code-behind ), similar to how MXML can be accompanied by an AS3 (.as file).

<fx:Script source="MyClass.as"/>

They are usually paired when creating views, the XAML portion deals with the layout and the code-behind can be used to handle any logic needed (click events, etc.).

XAML controls separate logic and their layout with ControlTemplates, similar to how Flex components use skins . This separation allows controls to have vastly different visual appearances while keeping the same functionality. For example, changing the appearance of a button control:

<Button>
     <Button.Template>
          <ControlTemplate>
               <Image Source="http://pathToSomeImage.png"/>
          </ControlTemplate>
      </Button.Template>
</Button>

This completely changes the default button to an image. However, certain controls will have a ContentTemplate as well. The main difference is that the ControlTemplate describes the visual layout of the control itself, but the ContentTemplate describes the visual layout of the content contained within the control. In the example above, the entire button would have been replaced with an image. But if all you wanted to do was tweak it so it displayed an image inside the button instead:

<Button>
     <Button.ContentTemplate>
          <DataTemplate>
               <Image Source="http://pathToSomeImage.png"/>
          </DataTemplate>
      </Button.ContentTemplate>
</Button>

Some controls will have ContentTemplates and others will have ItemTemplates. The difference is that some controls are meant to be populated with a set of data (like a ListView), and each item will be represented visually. In Flex terms, it is akin to a ItemRenderer.

<ListView ItemsSource=”{Binding PeopleListData}”>
     <ListView.ItemTemplate>
          <DataTemplate>
               <TextBlock Text=”{Binding Name}”/>
               <Image Source=”{Binding Pic}”/>
          </DataTemplate>
     </ListView.ItemTemplate>
</ListView>

A brief summary:

  • ControlTemplates describe the visual layout of the control itself
  • ContentTemplates describe the visual layout of the content contained in the control. Such as the content in buttons
  • ItemTemplates describe the visual layout of each piece of data represented in a control. Such as a single item in a ListView control, similar to Item Renderers in Flex/AS3

No matter which Template you end up modifying, the basic idea is that templates affect the visual layout of the control. In our example, customizing the ControlTemplate of an existing control is extremely simplified. Normally, it would require tweaking the default control template for that control. The default control template contains the control’s default visual states, transitions, and template bindings. More thorough explanations of styling can be found here and here .

One thing we noticed with the XAML controls is the lack of access to the source code. In Flex, the source for components can be found and viewed, which we had become accustomed to. However, it is possible to browse the metadata of a control withinVisual Studio, so you can see the publicly accessible properties and methods for it.

An exhaustive explanation about all the features of XAML is beyond the scope of this little blog entry, but additional functionality in the form of dependency properties , attached properties , binding , etc, helps make XAML stand out as a powerful approach to layout, comparable to MXML.

Since we mentioned the existence of default Control Templates, we should also point out where a reference to them can be found, which is here . However, the easiest way of getting access to the templates is typically from Blend, which brings us to…

Design with Blend

Microsoft Blend is a powerful WYSIWYG editor that dramatically enhances your ability to work with the visual aspects of XAML layout. It’s tightly integrated with Visual Studio (discussedhere), and generates the appropriate code for any values you tweak in the various toolbars and panels. We found our workflow usually bounced between Visual Studio for development and then back to Blend for design, as some XAML controls and styles are too complex to write by hand. There is some overlap since it’s possible to view XAML layout in “Design View” in Visual Studio and to edit code in “Code View” in Blend, but for the most part, development and design are split between these two.

Blend for Visual Studio 2013

As mentioned earlier, one area where Blend really comes into play is it’s ability to import and edit default ControlTemplates. This is the easiest way to dissect a control and customize it to your liking, without having to dig through the documentation and build it up from scratch. By selecting a control, you can choose to edit a copy of the default control template and have it applicable to that one control or replace all of a type throughout the application.

We didn’t always use Blend to build our views, but it was useful for being able to quickly see what a view would look like without the need to compile the application. This Live Preview is similar to what the Design View offered on Flash Builder (removed since version 4.7 or so) and turned out to be one of the more useful features of Blend. This feature, paired with the ability to configure design-time (fake) data to populate list boxes and other item renderers, gave our designers a quick way to work with layout and styling with great precision and the convenience of seeing their changes in real-time.

It’s a pretty solid development tool that allows both visual and code changes to the layout of an application. Speaking of development tools, let’s move on to…

Development with Visual Studio

Visual Studio 2013 (v12) was the Integrated Development Environment (IDE) we used for C# and XAML development. This is the equivalent of Flash Builder for AS3. They are both powerful tools that featured code-hinting, code-completion, debugging, profiling, testing, and build processes.

Visual Studio 2013

In Flash Builder, customizing the build process was fairly straightforward with Ant.Automation tools like Grunt are essential in JS development. MSBuild is another powerful tool available in Visual Studio, but has a learning curve, which seems to be a common trend in this environment.

One standout in Visual Studio is the great selection of extensions and plugins available for it. Some of the plugins we found useful in our workflow include CodeMaid and the Productivity Power Tools . CodeMaid allowed us to quickly clean up our code and remove unused imports (“using” directives in C# terms). Power Tools is a suite of little tweaks and upgrades to Visual Studio, such as the ability to ctrl+click a piece of code to peek at it’s definition, and error highlighting in the Solution explorer (the file tree of the project).

The ability to remotely run a debug version of our app on touch devices (such as the Surface) allowed the use of our monitors for fullscreen breakpointing and debugging. Being able to touch and interact with our applications on device helped us gain a better understanding of UX and performance in the real world. Simulators are available for both phone and surfaces, in case hardware is not available. There is also an “Immediate Window” which allows you to enter code and view the results while in a breakpoint. It is scoped to current context of the breakpoint you’re currently in, again useful for debugging and testing on the fly. These two debugging features heavily used in our workflow.

Visual Studio and Blend have their quirks, but what tool doesn’t? Overall it was a versatile environment that became more familiar over time.

Working with multiple projects in VS was handled with “Solutions”, which is akin to the “Workspaces” that Flash Builder offered. The ability to add multiple projects to a single solution was a nice touch, and is particularly handy when developing universal apps. This allowed us to have a distinct project targeting Windows, another targeting Windows Phone, and the codeshared between them.

There were some quirks and bugs that we found with VS, such as the need to clean the solution constantly, or even a full close and restart of the program to fix compiler issues. However, for the most part it worked nicely. The code-hinting, code completion, debugging options, profiling, and other features are on par with other modern, full featured IDE’s out there. Those used to Flash Builder for AS3 or WebStorm for JS will be able to find their way around VS. It’s pretty much just boils down to personal preference.

Visual Studio and Blend have their quirks, but what tool doesn’t? Overall it was a versatile environment that became more familiar over time.

On the subject of sharing code…

Sharing is Caring

Sharing code can be accomplished with the use of DLL’s or shared source files. DLL’s (dynamically linked libraries) can be created with Portable Class Libraries (PCL) in Visual Studio. They allow the sharing of code on the binary level. PCL’s are compiled into .dll files that can be imported into different projects. This is comparable to .swc files in Flash. However, there are some limitations with this approach. XAML is not supported in a PCL so you’re limited to sharing C# code only. Also, you are limited to a subset of the API’s available to the platforms you’re targeting. For example, the Windows.Phone.UI.Input.HardwareButtons class is not available in PCL projects because it is phone specific. This is done through the use of shared projects.

Since the introduction of the Universal app concept in Win 8.1/Win Phone 8.1, sharing source has been extended to sharing entire projects. Before this, code could be shared with linked source files, but on a single file by file basis. The basic premise is code that referenced/shared across projects and can be changed without the need to recompile a .dll file. One advantage of this approach is the availability of conditional compilation, so we can separate platform specific code, which is not available in PCLs.

Since PCL’s produce a binary file, it seems to be better for sharing among different and multiple projects. Due to the limitations of PCL’s (lack of conditional compiling and reduced API set depending on targeted platforms), the code contained within may need some higher levels of abstraction. Shared projects tend to be more suited for targeting different platforms in the same solution. Their support for conditional compiling is good for keeping a single codebase with tweaks for different platforms. However, it should be noted that this can get messy and unwieldy if not carefully managed. Also, shared projects with unit testing will need separate tests for each platform, whereas PCL’s will only require one.

The Little Things

Getting started definitely felt like slow process. Everything from the unfamiliarity with the API’s, syntax, framework paradigms, concepts, and workflows ensured plenty of reading during each step of the way. When starting from square one, even minor things such as tracing a message to console required referencing documentation:

System.Diagnostics.Debug.WriteLine("hello world");

We found that the MSDN docs are extensive, but it can get confusing with all the different versions of .NET and platforms floating out there. In contrast, the AS3 documentation seemed easier to filter through and find particular classes. However, this is understandable since the .NET framework is larger than the Flash/Flex platform as a whole.

.NET is a massive framework that encompasses class libraries, multiple languages (C#, Visual Basic, HTML/JS), and the Common Language Runtime (CLR). Since we were dealing specifically with Windows Store and Windows Phone Store apps, only a subset of the full .NET API’s were available to us. We had to be careful when looking up documentation to ensure that the classes/methods were actually supported on our target platforms. However, we should also note that since the release of Windows 8.1 and Windows Phone 8.1, the shared support of the Windows Runtime API (WinRT) has greatly simplified most of the issues we ran into.

Just to summarize and keep things clear:

In the End

Tackling a new language and technology stack proved to be a fun, interesting, and challenging endeavor. By pushing past our comfort zone, we added to our pool of knowledge and took the lessons we learned and applied them back to other technologies. In future articles, we may share our thoughts further on the learning curve, generics , tasks , error handling , and more.

For more information, check out:

Links

C# 5.0 in a Nutshell, 5th Edition: The Definitive Reference

An excellent in-depth book covering all aspects of the language.

http://www.dotnetperls.com/

Great website for quickly searching for terms, keywords, and concepts. Presents easy to understand explanations and examples.

https://msdn.microsoft.com/en-us/library/windows/apps/br211377.aspx

Windows API reference for Windows Runtime apps

https://dev.windows.com/en-us/getstarted

Dev Center for Windows Store Apps

https://msdn.microsoft.com/en-us/windows/hardware/gg507680

Dev Center for Windows Hardware (Phone) Apps





About List