C# tips, tricks and things you should know

By | November 14

.net components During my previous holidays (i have to admit 1.5 months surfing in portugal) I had some literature with me which also included the book Programming .net components released with O’Reilly. It talks about the aspects of components in general and provides good examples how to achieve those in .net. Although these pages are a very good read (rather for experienced devs) for ppl interested in component development, I found it more interesting because of its general C# content. There are concepts & approaches, small tips & tricks and intersting things about C# which can be used not only in component based architectures and are therefore good to know anyway.

As I always make notes while reading “geek” books I thought: “so why not summarize them all up in a nice list and blog’em”. Here we go…

1. implicit vs explicit interface
implicit interface implementation allows to use the interface member through an object or through the interface whereas the explicit interface implementation allows only access through the interface.

  1. //public interface IInterface {
  2.    void Foo();
  3. }
  4. //implicit implementation
  5. public AClass : IInterface {
  6.    public void Foo() { }
  7. }
  8. //explicit implementation
  9. public BClass : IInterface {
  10.    void IInterface.Foo() { }
  11. }
  12. //usage implicit
  13. AClass a = new AClass();
  14. a.Foo();
  15. IInterface b = new AClass();
  16. b.Foo();
  17. //usage explicit
  18. IInterface c = new BClass();
  19. c.Foo();
  20. BClass d = new BClass();
  21. d.Foo() //Fails because of explicit implementation!!!

Visual studio just offers the choice of the implementation but most people don’t know the difference. With explicit implementation the server (implementing the interface) can prevent clients from using it directly on object which implements it. It forces that the members of the interfaces are only accessible via the interface itself

2. implicit vs explicit cast
this is just to get used to the terminology because a lot of guys are using it but don’t know the terminology ;)

  1. //implicit cast
  2. T x = new T
  3. //explicit cast
  4. T x = (T)y
  5. //explicit cast (defensive)
  6. T x = y as T

Here you see that implicit casting is assigning a class instance directly to a variable. Explicit means casting from one type to another.

3. Destructors
A destructor of a class is defined with ~ClassName. In comparison to Dispose() the C# destructor is always called. Dispose() needs to be called by the client whereas the destructor is called when the garbage collector comes around. Best way is to implement both and channel the implementation to the method which does the cleanup. e.g. cleanup. Example of implementation [COMP05, 98]:

  1. public class MyBase : IDisposable {
  2.    private bool _disposed = false;
  3.    protected bool Disposed {
  4.       get {
  5.          lock(this) {
  6.             return _disposed;
  7.          }
  8.       }
  9.    }
  10.    public void Dispose() {
  11.       lock(this) {
  12.          if (!_disposed) {
  13.             CleanUp();
  14.             _disposed = true;
  15.             GC.SuppressFinalize(this);
  16.          }
  17.       }
  18.    }
  19.    //the method for the subclasses if they need to release resources
  20.    protected virtual void CleanUp() { }
  21.    ~MyBase{
  22.       CleanUp();
  23.    }
  24. }

Classes deriving from this baseclass can now implement their destruction by overriding the cleanup method and can now decide to do the clean up manually (calling Dispose) or leave it till the GC comes around. Important here is that if Dispose() was called we tell the garbage collector to exclude this instance from being garbaged later (with GC.SuppressFinalize()).

4. use “Using” defensive

  1. using (obj as IDisposable) {
  2. }

This approach will only call Dispose() if the object implements IDisposeable. Good if you dont really know if the object needs to release resources or not and if you want to be ready for future changes. e.g. the server decides to implement IDisposeable.

5. Delegate inference

  1. //instead
  2. publisher.someDelegate += new Delegate(someMethod)
  3. //u can use
  4. publisher.someDelegate += someMethod

This is much nicer to read but only supported with .net 2.0.

6. Custom event arguments
Custom event arguments (own class derrived from EventArgs) should have only readonly members. This prevents the client from changing the values. Readonly members can only be assigned in the constructor so the publisher of the event is able to set the values when creating the arguments.

7. Always fire events in a try catch block
You never know what the event handler method of the client does, so its good to put the firing into a try catch block. You could write your own EventsHelper class [COMP05, 144] for the purpose of firing event within your classes.

  1. public static class EventsHelper {
  2.    public static void Fire(Delegate d, params object[] args) {
  3.       if (d == null) return;
  4.       Delegate[] dels = d.GetInvocationList();
  5.       foreach(Delegate sind in dels) {
  6.          try {
  7.             sink.DynamicInvoke(args);
  8.          } catch {}
  9.       }
  10.    }
  11. }

8. use “property-like” approach for event accessors
As you do with common member variables (expressing them with properties) you also should do this with events. This alows you to control the adding and removing of event handlers for your event.

  1. public class MyClass {
  2.    MyHandler _myEvent;
  3.    public event MyHandler MyEvent {
  4.       add {
  5.          _myEvent += value;
  6.       }
  7.       remove {
  8.          _myEvent -= value;
  9.       }
  10.    }
  11. }

9. Static objects as keys

  1. static name = new Object();
  2. myCollection[name] = "a name"
  3. //instead of (old school)
  4. myCollection["name"] = "a name"

a static object is created to act as a key for e.g. collections (because every instance is unique - has its own identity!). The advantage in comparison to the “old school” version (key is a string) is that the key is already available in memory wheras the string needs to be created everytime. If you use this key in a lot of places it could save some time.

10. Combine enumeration values

  1. public enum color {
  2.    red,
  3.    green,
  4.    all = red | green
  5. }

This example illustrates that it is possible to have enumeration values which accept more than one existing values of the current enumeration.

11. Singelton Application
A singelton application is one which only allows running one instance per machine. e.g. Microsoft Outlook is a singelton application. Everytime the user starts the application it will check if an instance is already running. If its not running it will launch it otherwise it will focus to the current one. The source for an application which runs only once is available in another post “Singelton Application with C#

12. Containment
If it is not possible to derive from a class we use a class to wrap around the class we would like to inherit from. This procedure is also known as “Containment” (I mention it here because the this term is more unknown - usually developers use wrapper)

13. Use Debug.Assert()
The use of Debug.Assert should be used as often as possible. During the development the developer should “assert” things which always should be true. This helps finding bugs easier and its easier for other developers to understand the code.

  1. int a = 10
  2. int b = 20
  3. int c = 20 - 10
  4. Debug.Assert(c > 0, "i need it bigger than 0. check might be done in the future")
  5. Console.WriteLine(10 / c)

This short example demonstrates that obviously the developer expects the variable “c” to be greater than 0. Why? Because in the next line he/she uses it for a dvision which would break with c = 0. If this is the case you would get an information seen in line 4. This concept is nice because it makes comments “active”.

14. user string instead of String
String is just an alias for string and therefore its nicer to use the original type straight away. The same with int and Int32, etc.

15. Rethrowing exceptions

  1. try {
  2. } catch(Exception e) {
  3.    //some logging,etc...
  4.    throw;
  5. }

This piece of code rethrows the exception. The interesting thing here is that you dont need to specify the Exception explicitly. Just the keyword “throw” is enough to rethrow the exception.

15. Code exclusion with attributes and not with #if .. #endif

  1. [Conditional("DEBUG")]
  2. void Foo() {
  3. }

The advantage here is that the code is not reachable anymore if the condition is not met. This means that it will result in compile errors if you reference this method. #if … #endif does not enforce this constraint. Its also nicer than the hash signs ;) Please check the MSDN Reference for more details about the conditional attribute.

Thats was it :) Hope there was something interesting and maybe new for everyone. I dont want to promote the book here but I really recommend it because it contains good content about programming with c# (and especially for component development) and should be read by every C# developer who wants to develop for enterprise.

Maybe you have some interesting tips & tricks which might be useful for others. Please be so nice and comment them… I am interested.

Resources:
[COMP05] .net Components, Juval Löwy, O’Reilly United States

7 comments on “C# tips, tricks and things you should know

  1. Really worthful tip and tricks on C#. :)

  2. This is an impressive and very useful set of tips. Thanks for taking the time to post these.

  3. Great article!
    Just a small thought: its Singelton or Singleton App?

  4. Point 8 is only useful if you do something with it. The code you have is essentially what would be generated for you.

  5. Uh, this list is full of errors and bad advise.

    >implicit vs explicit cast

    There is a bigger difference here that they don’t touch on. Casting via

    lol = (foo)bar;

    will throw a invalid cast exception if the cast can’t happen. However the same this way:

    lol = bar as foo;

    Will fail silently and just set lol to null. This means you need to be aware and check for nulls. Additionally, this cast is slower because it catches the invalidcast exception under the hood.

    >Destructors Best way is to implement both and channel the implementation to the method which does the cleanup

    Garbage collection in .NET is non deterministic, so your destructor is not called when the object goes out of scope, but instead when there is heap pressure. Because of this, you should never free resources in a finalizer (They aren’t officially called destructors either), otherwise your app could hold open resource handles indefinitely.

    Instead you should always implement the IDisposable pattern.

    >use “Using” defensive This approach will only call Dispose() if the object implements IDisposeable. Good if you dont really know if the object needs to release resources or not and if you want to be ready for future changes. e.g. the server decides to implement IDisposeable.

    This will actually not compile unless the object already implements IDisposable, so this is entirely incorrect.

    > 1. Always fire events in a try catch block You never know what the event handler method of the client does, so its good to put the firing into a try catch block. You could write your own EventsHelper class [COMP05, 144] for the purpose of firing event within your classes.

    The provided example goes against every best practice known to .NET programmer.

    * Fail Fast
    * Never eat unhandled exceptions
    * Never catch exceptions just to rethrow.

    Utter garbage, ignore this one.

    >1. Static objects as keys a static object is created to act as a key for e.g. collections (because every instance is unique - has its own identity!). The advantage in comparison to the “old school” version (key is a string) is that the key is already available in memory wheras the string needs to be created everytime. If you use this key in a lot of places it could save some time.

    This would only make sense if the C# compiler and CLR didn’t automatically fold strings, so that each string literal is only referenced once. This means that if you have a literal “foo” in your code, the CLR will create it once, and reuse the pointer to it under the hood.

    This means that this “performance gain” is bogus, and just leaves really shitty code.

    >Containment

    This should be Composition.

    • Jonathan I really appreciate your extended feedback and agree with most of the things however keep in mind that this book is focused on component development/usage .

      Just some things to add from my side:

      Instead you should always implement the IDisposable pattern.
      

      It’s already mentioned … “best way is to implement both”

      This will actually not compile unless the object already implements IDisposable, so this is entirely incorrect.
      

      Hmm, actually it will compile as there is a defensive cast (see 2.) within the using statement. If IDisposable is not implemented then the cast results in null and dispose is not called. Therefore “defensive” and fully legal.

      The provided example goes against every best practice known to .NET programmer.
      * Fail Fast
      * Never eat unhandled exceptions
      * Never catch exceptions just to rethrow.
      Utter garbage, ignore this one
      

      Totally agree with you on this and am not 100% sure why they do it that way but I guess it has to do with components development. Will look that up again as soon as I am home and have access to the book.

      >1. Static objects as keys a static object
      

      I guess the big benefit here is type safety and intellisense. I am not sure about your explanation with the CLR and folding strings. Could you explain this in detail. Afaik strings are immutable and therefore each string exists once in the string pool. Static object would also exist only once. So I guess it would be pretty much the same from an performance point of view .. Unless the object is “smaller” than the string object… not sure if I am correct.

  6. Great tips,

    But the tip 14 is wrong, string, in C#, is a alias to System.String in CTS (Common Type System), as well Integer (VB.NET) and int (C#) is a alias to System.Int32