(X) Hide this
    • Login
    • Join
      • Say No Bots Generate New Image
        By clicking 'Register' you accept the terms of use .

WP7 for iPhone and Android Developers - Introduction to C#

(4 votes)
Kevin Hoffman
>
Kevin Hoffman
Joined Feb 01, 2011
Articles:   10
Comments:   1
More Articles
6 comments   /   posted on Feb 15, 2011
Categories:   Windows Phone , General

This article is part 1 from a 12-part article series on Windows Phone 7 for iPhone and Android Developers.

This article will provide an introduction to the basic concepts of writing code in C# for those of you already familiar with Java from Android development or with Objective-C from iPhone and iPad development. If you’re already a .NET developer and you’ve been building ASP.NET applications and you’re interested in learning how to write WP7 apps, then feel free to skip to the next article in this series. The ultimate goal of this series of articles is to prepare you for writing Windows Phone 7 applications, whether your background is in ASP.NET, Android, iPhone, or iPad development.

The first thing developers notice about C# is how much it looks like C or C++. This is not a coincidence. Contrary to popular belief, C# was inspired by C and C++ and was not inspired by Java. If you’ve seen Java, Objective-C, and C# code side-by-side and you’ve thought about how similar they look at times, you’re not alone. All three of these languages owe much of their heritage to the original ANSI C language. In fact, Objective-C is actually a functioning superset of ANSI C so it does more than borrow it’s heritage from C, it’s a direct descendant.

Like Java and Objective-C, C# is an Object-Oriented programming language. As an iOS or Android developer you should probably be very familiar with basic OOP concepts like encapsulation, inheritance, and accessors. Fortunately, the C# language looks enough like Java and Objective-C that basic arithmetic and even some conditional logic operators are indistinguishable among the three languages.

For example, in the following bit of code, it is impossible to tell which language we’re using without additional context:

 int a=5;
 int b=10;
 int c;
 c = a + b;
 while (c > 1)
 {
   c -= 1;
 }

The code here is pretty primitive but it illustrates an important point – while there are syntactic differences in the languages, the biggest difference in idiomatic code samples across the three languages isn’t the language itself: it’s the nature and design of base classes being used. When you look at code samples for the iPhone, what you notice is UIKit and heavy use of the delegate pattern and MVC (Model-View-Controller), the fact that the language being used is Objective-C becomes secondary. When you’re looking at Android code, you notice the Android development framework and the underlying APIs more than you notice Java. The same is true for Windows Phone 7 – what you notice when building WP7 code is the extensive use of Silverlight, the base classes that belong to the .NET Framework, and the various device APIs.

Future articles in this series will introduce you to these APIs when we get into the nuts and bolts of actual Windows Phone 7 programming. For now, this article’s goal is to provide you with a quick look at C# so that, as you progress through this series of articles, you can concentrate on the work at hand without letting the language syntax get in your way.

Memory Management

If you’ve been developing iOS or even desktop applications for the Mac then you should be familiar with how memory is managed in Objective-C. At one point in Objective-C’s past was actually little more than a set of symbols that mapped to method calls to add Smalltalk-like object-oriented functionality. To handle the fact that pointers to objects regularly get passed around to multiple other objects, often simultaneously, Objective-C adopted a reference counting scheme. Anytime an object needs an instance of another object to stay around long enough to get work done, the containing object (often called an owner) retains that object. When it is done with that object and can get along without it, it will release that object.

Let’s say you have a game engine class that holds references to all of the various objects currently participating in the game such as the game board, game pieces, and other objects such as a scoreboard. The game board has references to the game pieces but so do the player objects owning said pieces. If a player object decides that it’s done with a particular game piece, it can’t simply deallocate the memory for that object because it doesn’t know who else is using that particular object at the time. A standard solution to this problem that is used by more languages than just Objective-C is reference counting. Every time an object becomes the owner of another object, it will increment it’s reference count by 1. In iOS, you do this with the retain message as shown below:

 [mySubView retain];

When an object relinquishes ownership of an object, it can then decrement the object’s reference count. In iOS this is done by sending the release message:

 [mySubView release];

Objective-C has many facilities for making reference counting easier such as autorelease pools which, when drained, will force every object contained within the pool to decrement its reference count by one. A problem that many iOS developers, myself included, have to deal with on a daily basis is tracking down memory leaks. It can get very easy to “over retain” an object, preventing its memory from ever being reclaimed. You can also prematurely release an object so that the next time you try and do anything useful with that object, unpredictable results (up to and including an app crash) can occur.

Introducing Garbage Collection (and there was much rejoicing)

Now that I’ve reviewed the pain and suffering that is the burden of every iPhone developer, let me just tell you that Windows Phone 7 has no such burden: there is no reference counting on this platform. Like Java, C# is a garbage collected language. Objective-C relies on you to keep track of which objects own which other objects and at what point it is acceptable for those objects to be removed from memory. I don’t know about you, but I get uncomfortable anytime anything relies on me to function properly.

In a garbage-collected runtime, there is an omnipresent helper keeping track of everything your code allocates. In C#, it does so by maintaining a tree of “roots”. Rather than manual referencing counting, C#’s garbage collector works by root counting. It keeps track of all of the paths to objects allocated on the heap. When the garbage collector runs periodically, it will seek out all of the orphaned objects that can no longer be reached (this would be like having a reference count of 0 in iOS) and dispose of them.

While garbage collection frees you of the burden of manually managing your own reference counts, this doesn’t give you carte blanche to utterly abuse your application’s heap. Collecting objects and re-organizing free memory on the heap takes time. The more stuff you keep lying around the slower your garbage collection will be. Also, if you are rapidly allocating and de-allocating objects over and over (such as in tight loops) you could also create garbage collection performance problems.

in general, the garbage collector rarely makes its presence known and if you keep your code clean and tight and are fairly responsible with the memory you consume, then you should find the development experience in C# to be much less stressful when it comes to memory management and tracking down memory leaks.

Hello Zombie

To illustrate what some straightforward C# looks like without getting bogged down by the horror of standard “Hello World” applications, I’ll show you a class that exhibits some of the most classic examples of C# programming, including inheritance, interfaces (contract-based programming, or ‘protocols’ to you iOS developers), abstract base classes, properties, methods, and more all without printing '”Hello World” to a console screen.

In this sample, we’re going to build a few classes that might be at home within a game engine. This game engine could be a mobile WP7 game engine or web-based, it doesn’t really matter. The point of these classes is to illustrate some very clear, idiomatic C# and relate that to concepts that might be familiar to Java and Objective-C developers.

First, we know that we’re going to have combatants in the game. Since none of the three languages allow for multiple inheritance, we’re probably already used to the following problem: How do we make a bunch of things able to participate in combat without making them all part of the same inheritance tree? In other words, we want to be able to fight monsters, humans, or maybe even magically animated coffee tables. To do this, we want to create a contract (in C# we call them interfaces, Objective-C calls them protocols). Anything that conforms to this interface, regardless of its inheritance hierarchy, will be able to respond to combat. In other words, if our game engine sees an object of type ICombatant, it knows that it can engage in a fight.

Here’s a look at the ICombatant interface:

 public interface ICombatant
 {
     int HitPoints { get; }
     string Name { get; }
  
     void GetHit(ICombatant attacker);
     void Attack(ICombatant target);
 }

This interface tells us that any combatant in the game needs to be able to report (read-only) it’s hit points and needs to expose a read-only property so the game engine can identify the name of the combatant. In addition, every combatant needs to expose two methods: one to respond to being attacked and one to initiate an attack on another combatant.

In the Java world, you may not be used to properties, so the contract to which your Java class would conform would have a single “get” accessor method called getHitPoints() and another accessor method called getName(). In Objective-C, you might declare your property like this:

 @protocol CombatantProtocol <NSObject> 
 @required
 @property(readonly) NSNumber *hitPoints;
 @end

This same interface in Java might look something like this:

 interface Combatant
 {
     int getHitPoints();
     String getName();
  
     void GetHit(Combatant attacker);
     void Attack(Combatant target);
 }

Remember that this is a contract and not actual implementation code. So whether we’re looking at C#, Java, or Objective-C code, we’re only describing what the real class must do. In other words, it is up to the implementation of the class to decide how it should support the HitPoints property. As a side note, you may have noticed that instead of using a regular “int” I used an NSNumber pointer. This is because Objective-C is real ANSI C and as such, it’s int type is nothing more than that. Java and C# both treat integers like objects. Even though I used the C# keyword “int” it will actually compile as a System.Int32 object, which has methods on it like ToString() and other handy methods that a C integer doesn’t have. This is why it’s customary in iOS development to use NSNumber pointers rather than their scalar counterparts, especially because in iOS you cannot add ints to collections but you can add NSNumber objects.

Now that we have a contract, we need a class to implement it. We’ve all been around the Object-Oriented Programming block a few times so we know that we’re probably not going to want to start directly with a Zombie class. Instead, let’s create an abstract class (one that cannot be instantiated but rather only serves as a parent class to the real classes) called Monster, from which we can derive other classes like Zombie or Vampire or MotherInLaw (you know I’m right…)

Here’s our Monster class:

 public abstract class Monster : ICombatant
 {
     private int hitPoints;        
  
     #region ICombatant implementation
     public int HitPoints
     {
         get { return hitPoints; }
     }
   
     public virtual string Name { get { return "Monster"; } }
         
     public void GetHit(ICombatant attacker)
     {
         OnHitByAttacker(attacker); 
     }
   
      public void Attack(ICombatant target)
     {
         OnAttackedTarget(target);
      }
      #endregion
   
      protected virtual void Say(string message)
      {
         Console.WriteLine(Name + " says: " + message);
      }
  
     /// <summary>
     /// To be implemented by deriving classes
     /// </summary>
     /// <param name="attacker"></param>
      protected virtual void OnHitByAttacker(ICombatant attacker)
      {
      }
   
      /// <summary>
      /// To be implemented by deriving classes
     /// </summary>
      /// <param name="target"></param>
      protected virtual void OnAttackedTarget(ICombatant target)
      {
      }
 }

Now we’re getting into some C# that is a little bit more involved and starting to look a bit less like Objective-C and Java. First there’s a class member called hitPoints that provides the backing store for a public (read-only) property called HitPoints. Just like Objective-C and Java, C# is case-sensitive.

Next there’s a read-only property called Name. I’ve marked it virtual because I want deriving classes to be able to provide a replacement implementation. In other words, I want the Zombie class to be able to identify itself as “Zombie” to the game engine rather than just identifying itself as “Monster”. Next up are the two methods required by the ICombatant interface. Here we invoke some virtual methods. This allows the deriving classes to override the OnHitByAttacker and OnAttackedTarget methods. You’ll see this type of pattern used regularly in C# and Windows Phone 7 programming. Using this pattern we can provide some standard behavior that every monster does and then provide enhancements or customizations to this behavior in deriving classes. For example, we could make a type of monster that always runs away screaming like a little baby whenever it gets attacked or another monster that calls for help and summons a bunch of other monsters to it when it gets attacked.

Now that we’ve got a standard Monster class, let’s see what a typical Zombie class might look like:

 public class Zombie : Monster
 {
     protected override void Say(string message)
     {
         Console.WriteLine(Name + " slobbers: " + message);
     }
  
     public override string Name
     {
         get
         {
             return "Zombie";
         }
     }
     protected override void OnAttackedTarget(ICombatant target)
     {
         base.OnAttackedTarget(target);
     }
  
     protected override void OnHitByAttacker(ICombatant attacker)
     {
         base.OnHitByAttacker(attacker);
         Say("BRAAAAAIIINNNNSSSSSS!!1");
         Attack(attacker);
     }
 }

Finally we’ve got a class that we can instantiate and that our (entirely hypothetical and nonexistent) game engine can utilize. The first thing we do in our Zombie class is override the Say method so that instead of “saying” text, our monster “slobbers” the text. This adds a little character to the game and allows different monsters of different types to speak with their own style.

Next we override the Name property to return the text “Zombie”. The OnAttackedTarget overridden method has no custom logic in it now but we could easily expand that to do something interesting, such as eventually adding support for brain-sucking or other flesh-tearing maneuvers that are typical zombie attacks.

Finally I overrode the OnHitByAttacker method. The "base.OnHitByAttacker(attacker);” method call will invoke whatever code resides in the Monster base class. No zombie is truly a zombie without shouting the classic “BRAINS!” phrase upon being hit by someone else. In response to being attacked, our zombie simply returns the favor.

Let’s recap some of the basic C# language features we’ve discussed up to this point:

  • Basic language features like conditionals and arithmetic
  • Memory management and garbage collection
  • Basic OOP like creating a class
  • Inheritance (Zombie inherits from Monster)
  • Interfaces (the Monster abstract class implements the ICombatant interface)

Armed with the information in this article, you’re ready to continue on to subsequent articles in this series where I will talk about basic and advanced UI techniques, push notifications, going from MVC to MVVM, utilizing device hardware like cameras and even FM radios, and much more.

About the Author

Kevin Hoffman (http://www.kotancode.com/) is a Systems Architect for Oakleaf Waste Management (http://www.oakleafwaste.com/), freelance developer, and author of multiple books including the upcoming WP7 for iPhone Developers and co-author of books such as ASP.NET 4 Unleashed and SharePoint 2007 Development Unleashed. He is the author of the Kotan Code blog and has presented at Apple's WWDC twice and guest lectured at Columbia University on iPhone development.

 


Subscribe

Comments

  • -_-

    RE: WP7 for iPhone and Android Developers - Introduction to C#


    posted by Tony on Feb 15, 2011 18:26

    Very nice and fun to read.

    Thanks!

  • -_-

    RE: WP7 for iPhone and Android Developers - Introduction to C#


    posted by stephc on May 12, 2011 20:39

    This is absolute crap.

    I stopped reading after the Memory Management bullshit, GC is one of the worst invention ever.

    I consider developers who don't even know how to use memory properly to be stupid newbs.

    Give me C++/OpenGL.

    We don't need dumbed down tools, period.

    Microsoft is losing mind share very quickly here, especially among experienced games developers.




  • -_-

    RE: WP7 for iPhone and Android Developers - Introduction to C#


    posted by Kevin Hoffman on May 12, 2011 20:52

    There's a fine line between flaming and presenting your own viewpoint. As mentioned in the article, garbage collection is a convenience that allows developers to (ideally) spend more time thinking about how their application is going to work and less time thinking about how many other objects are referring to other objects, and so on. Also mentioned in the article - this is not an excuse for throwing caution to the wind and thinking "i'm in a GC'd environment, I can do whatever the hell I want". Both GC and reference counting have their own pros and cons and it is arguably a matter of -opinion- as to whether you prefer one over the other.

  • -_-

    RE: WP7 for iPhone and Android Developers - Introduction to C#


    posted by Kevin Hoffman on May 12, 2011 20:56

    It is worth noting that a very large number of games... commercial, high-budget, successful games ... for the Xbox 360 were developed using XNA. That means managed, garbage-collected code. The idea that the mere presence of garbage collection causes such a performance hit that it should be shunned unilaterally is myopic. It isn't the presence of GC that makes a system perform slowly - it's what the developer does with their own objects that can cause the GC to perform poorly or properly. 

  • -_-

    RE: WP7 for iPhone and Android Developers - Introduction to C#


    posted by stephc on May 13, 2011 11:53

    I agree one this point : it's a matter of opinion, and choice.

    The problem is when we don't have choice to use a different memory management policy.

    There is something I don't get, why are you considering that the job should be made easier?

    You may attract some new, inexperienced developers, lazy or not-so-smart guys, but where is the value in this?

    It's pretty hard to consider that products created with "simpler" tools will be better in the end, in my world, this is quite the opposite.

    Look twice at the XBox, all the retail games are made with C++, all XBLA games too, only the "amateur" games are made with XNA.

    PS2 and PS3 are notoriously hard to program for, but look at the games... 



  • SocalSam

    Re: WP7 for iPhone and Android Developers - Introduction to C#


    posted by SocalSam on Jul 24, 2011 21:09

    The tools and garbage collection argument, seriously?  The worse programs that I ever encountered are written by people who think they can do better than the GC.  Usually the programmers who insist that the use of tools to simplify or the GC to make sure to use the builtin memory management do not play with others.

    Accusing people who use built in tools is like the John Henry myth in the United States.  Old John Henry used the sledgehammer to drive those railroad spikes and couldn't win against the steam hammer.  Take a lesson, the tools that simplify and the GC will win.  There is too much computing power to force the creative minds to put up with C++, or even long term Java or C#.  The creative don't want to struggle with the arcane processes of object oriented software.

    So if you think that C++, or even any object oriented programming language will remain for the creative groups of people, then it is time to move on and get more efficient.  C++ and it's family will be used for tools for awhile and then disappear as the powerful computers/consoles of the future come into play.

    Bottom line: Quit accusing the non-programming, but creative people of being newbs, frankly they are only going to need the "toolmakers" for a short time.  Software is a service, and the human race lived for many millenium without it.

Add Comment

Login to comment:
  *      *       

From this series