9 reasons why I LOVE C#

I always enjoyed coding in c++. But coding in C# makes coding in c++ feel like coding in assembly. Here’s 9 reasons why I love it.

No Headers

It’s not until you stop using headers until you realise how stupidly archaic they are.

Var

Using var means you don’t have to actually declare the type. The compiler can work that shit out for itself! This is one of those things that you don’t appreciate when you hear about it.. but when you start using it you really do.

// c++
int myvariable = GetHealth();

// c#
var myvariable = GetHealth();

You can still use int in the c# version if you like, and I’m sure there’s purists that say that you shouldn’t even use var for some reason.

LINQ

I haven’t even scratched the surface of knowing what Linq is all about.. but I know this is cool. Imagine you need to find a player by playerID in a list of players. I appreciate that you’d have probably wrapped all your ugly c++ with macro’s or you’ll be using some super complicated Boost library in c++.. but for arguments sake

// c++
MyPlayer player = null;
for (std::list::const_iterator it = playerList.begin(), end = playerList.end(); it!= end; ++it ) 
{
    if ( (*iterator)->PlayerID == FindID )
    {
        player  = *iterator;
        break;
    }
}

// c#
var player = PlayerList.Find( x => x.PlayerID == FindID );

Yep that’s right. It’s like writing an inline function. It feels like cheating.

var notPlayers = PlayerList.FindAll( x => x.PlayerID != FindID );
var banPlayer = PlayerList.Find( x => x.Username!= BanName );

Attributes

If you’ve ever written a class factory in C++ you will appreciate attributes. So you make this function..

public class ConVar: Attribute
{
    public string help = "";

    public ConVar( string help )
    {
        this.help = help;
    }
}

Now in any class in your code you can do this..

[ConVar( "Start health of player" )]
static public float health = 4.5f;

[ConVar( "Player's name" )]
static public string name = "Unnammed";

Now on startup you can make your program find every ConVar attribute and set them up in a dictionary by field name. Then you can add functions to get and change their values. You just made a convar system.

It’s kind of an excited feature once you start digging into it, there are tons of possible uses.

No Macros, templates

Like headers, a lot of c#’s strengths come from the things it doesn’t provide. It’s simple and easy. It doesn’t encourage you to change the language. Sometimes coding in c++ is like writing your own language for things and fooling the compiler into working for you.

Named Arguments

You ever had a function with tons of arguments, or even worse – a ton of optional arguments?

int MyFunction( string shirt = "", string shoes = "", int numEyes = 2, float time = 5.0f )
{
    // Do Something
}

MyFunction( shoes: "Trainers" );
MyFunction( time : 2.0f, shirt: "white" );

It’s another one of those things that seems useless, but is really nice.

Interface, Abstract

In C++ you can kind of make an interface but it’s never really proper. With Interface and Abtsract classes in c# you know exactly where you are.

64 Bit

Converting c++ code to work in 64bit is a bit of a mine field. You might get it compiling.. but you never really know whether your code is actually going to be doing bad things unless you have either designed it from scratch for 64bit, or you have gone line by line and verified.

In C# chances are your code is going to just work. Unless you’re doing some really really specific things. To me this sums up C#. It shows how abandoned and old fashioned c++ is.

Mono

Thanks to Mono all this stuff isn’t bound to Windows. It kind of makes your investment in learning c# less useless.

Summary

C++ is never going to go away. It’s probably always going to be the bedrock of everything. But maybe it’s time to re-evaluate whether everything should be coded in C++ by default. Maybe it’s time to think about the future. Writing less error-prone, more future-proof code.

34 thoughts on “9 reasons why I LOVE C#

  1. To be fair, C++ is evolving very well, for your “var” we have:

    auto myvariable = GetHealth();

    and for your LINQ (which is not really LINQ what you described but just a lambda) we have:

    auto player = find_if(begin(playerList), end(playerList), [FindID](const Player& p) { return p.PlayerID == FindID; });

    Also, unless you use crappy fixed types or low-level bit trickery, 64bit is a non-issue.

    1. You are correct that the Lambda is not directly LINQ, but different Lambda functions use LINQ Query patterns internally. ‘Find’ is one of them, along with ‘Where’ and some others.

  2. There’s good news for those sticking with C++: some of these criticisms have been or are being addressed in C++.

    * No Headers: People around the Clang project, many of them Apple employees, are preparing a “Modules” proposal to get rid of header file inclusion. (Frickin’ finally…)

    * Var: C++11 repurposes the utterly useless “auto” keyword to do exactly what “var” does in C#.

    * LINQ: LINQ is effectively lambda expressions plus a bunch of extremely useful standard functions that use them. C++11 introduces lambda function support; I’m not sure how well the standard library was improved to allow their efficient usage, though.

    * Attributes: C# (and Java and many other programming languages) win this one: C++ supports pretty much zero reflective programming as it stands, so no support for attributes either.

    * No macros, templates: Can’t say much about this, of course. :D

    * Named Arguments: No progress here that I know of.

    * Interface, Abstract: C++’s support of multiple inheritance is a design specialty that was abandoned by most successors. (Eiffel still does it, and does it pretty well, from what I’ve gathered.) Like macros and templates, I can’t say much about it.

    * 64 Bit: Yup, C# is nicer here, mostly because the integer sizes are all precisely defined and the runtime hides all the bitness differences.

    * Mono: Well, you have a few platform-abstraction libraries for C and C++, but you have to know about them in advance. Mono implementing Microsoft’s .NET class library is a hell lot easier.

    So yes, C# is a lot less annoying for many day-to-day things, but for those who (have to) stick with C++, things are getting less annoying too.

    1. I was just about to comment with ‘they’ve added auto to c++’. Nice comprehensive post. :)

    2. I’m not entirely sure how, but Unreal Engine 4 uses attributes extensively. They have a reflection system they developed for c++. I haven’t look to deeply into how it works yet, but just showing that its possible.

  3. I always thought that one of the shortcomings of C# was that you could not create a function taking optional arguments. Is this not the case anymore?

  4. I love C# so hard. I’ve been doing Android development and Java feels like a huge step backwards. (though they’re adding some things like lambdas in Java 8)

  5. I can’t understand why people often want to use things like “var” or “auto” (c++). For me it makes things more complicated.
    The only case where I use this is if iterating:
    std::vector mPlayerList;
    for (auto itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr)
    (*itr)->ban();

    I will stay at C++, because it is more “strict” and kind of more logical for me… Also the performance of C++ is of course better, especially if developing games or server software.
    It is also easy to write software which is cross-platform if libraries like Boost or QT are used.

    I also program microcontrollers, so there is no way for me to use something different than C/C++ :)

  6. Once you start doing a lot of C#, you get into the really cool features of C#/.NET:

    Run-time Code Reflection/Generation/Compilation w/ Expression Trees (most of the really cool stuff with LINQ is accomplished this way; i.e. LINQ to SQL):
    http://msdn.microsoft.com/en-us/library/bb397951.aspx

    Assigning templated interfaces to similar but not quite the same templated types; i.e. why are you allowed to assign an IEnumerable object to an IEnumerable variable, or pass an IDictionary variable to a method expecting an IDictionary type:
    http://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

    Static Extension Methods (used very extensively on the IEnumerable interface):
    http://msdn.microsoft.com/en-us/library/bb383977.aspx

    Easy Parallel Execution for CPU-bound tasks:
    http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel_methods(v=vs.110).aspx

    The TPL + async/await makes IO-bound tasks stupidly easy:
    http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
    http://msdn.microsoft.com/en-us/library/hh191443.aspx

    Easily handling post-to-UI-thread type scenarios:
    http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx

    And then there’s the bleeding edge stuff that just came out of //build this year:

    Compiler-As-A-Service with Roslyn:
    http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx

    Write tablet/phone applications in C# for all platforms:
    https://xamarin.com/

    Compile to native:
    http://msdn.microsoft.com/en-US/vstudio/dotnetnative

    And of course, there’s NuGet:
    http://www.nuget.org/

    1. Whoops – let’s try that again, but with curly braces instead of angle brackets.

      #2: why are you allowed to assign an IEnumerable{string} object to an IEnumerable{object} variable, or pass an IDictionary{string,string} variable to a method expecting an IDictionary{object, object} type.

  7. nt MyFunction( string shirt = “”, string faggot = “”, int numEyes = 2, float time = 5.0f )
    {
    // Do Something
    }

    MyFunction( faggot: “Garry Newman” );
    MyFunction( time : 2.0f, shirt: “rainbow” );

    There I fixed it.

  8. Got into C# when I started doing a Unity3D project for work. We fell in love at first sight.

  9. I’ve never understood why C# doesn’t let you use unsigned types for accessing array elements. Doing

    int[] numbers = {1,2,3, -10, 50, 100};
    for(uint i = 0; i < numbers.Length; i++){
    Console.WriteLine(numbers[i]);
    }

    Throws an error? Why? Array indices must ALWAYS start at zero, so why do you make me use a signed type to access array elements?

  10. So when will we see C# replacing Lua in gmod? (I don’t care it’s not a scripting language per se).

Comments are closed.