c#Faqs

C# Frequently Asked Questions

The C# team posts answers to common questions

  • Why does my switch statement works differently?

    C# does not support an explicit fall through for case blocks (unless the block is empty)
    For an explanation of why, see Why is the C# switch statement designed to not allow fall through, but still require a break? on MSDN
    The following code is not legal and will not compile in C#:

    switch (x)
    
    {
    
    case 0:
    Console.WriteLine(x) // do something
    case 1:
    Console.WriteLine(x) // do something in common with 0
    default:
    Console.WriteLine(x) // do something in common with 0, 1 and everything else
    break;
    } In order to achieve the same effect in C# the code must be modified as shown below (notice how the control flows are very explicit): class Test {
    static void Main() {
    int x = 3; switch (x) {
    case 0:
    // do something goto case 1;
    case 1:
    // do something in common with 0 goto default;
    default:
    // do something in common with 0, 1, and anything else break;
    }
    }
    }


  • Why does C#’s iterators feature spit out a class definition instead of a struct definition?

    Q: Why does C#’s iterators feature spit out a class definition instead of a struct definition?
    The iterators feature in C# generates classes that implement the enumerators required. This is detailed in the C# Specification. Why doesn’t it use structs, which would be more efficient.
    A:
    There are two reasons.
    (1) Naming. We generate classes that implement the enumerator interfaces and then use only the interface types in the public protocol. That way the names of the generated classes are purely an implementation detail. This is highly desirable from a versioning perspective. With a struct-based implementation, to get any of the efficiencies associated with structs we would have to use their types in the public protocol (using interfaces the structs would just get boxed). That in turns means we’d have to invent a name mangling scheme for the structs. In particular, iterators returning IEnumerable<T> would be complicated because a type could have multiple such members that differ only in their parameter list, meaning that the parameter list would have to be part of the mangled name.
    (2) Structs don’t work in recursive cases. For example, a TreeNode type could implement an iterator that recursively iterates first the left and then the right subtrees by foreach-ing contained members that are also of type TreeNode. With a struct-based implementation this would translate into an enumerator struct that contains a field of its own type–which isn’t possible. (Think of it this way: A foreach statement obtains an enumerator and stores that in a local variable. In iterators, local variables are transformed into fields in the enumerator. A recursive iterator would therefore create a struct with a member of its own type.) You could argue that we can detect whether or not iterators are recursive and adjust our code generation scheme accordingly. However, you then end up with a versioning problem when a previously non-recursive iterator changes its (supposedly private) implementation to become recursive.
    Anders (via Eric)
  • How can I run another application or batch file from my Visual C# .NET code?

    Posted by: Duncan Mackenzie, MSDN
    This post applies to Visual C# .NET 2002/2003
    Suppose you want to run a command line application, open up another Windows program, or even bring up the default web browser or email program… how can you do this from your C# code?
    The answer for all of these examples is the same, you can use the classes and methods in System.Diagnostics.Process to accomplish these tasks and more.
    Example 1. Running a command line application, without concern for the results:

    private void simpleRun_Click(object sender, System.EventArgs e){
     System.Diagnostics.Process.Start(@"C:\listfiles.bat");
    }

    Example 2. Retrieving the results and waiting until the process stops (running the process synchronously):

    private void runSyncAndGetResults_Click(object sender, System.EventArgs e){
     System.Diagnostics.ProcessStartInfo psi =
       new System.Diagnostics.ProcessStartInfo(@"C:\listfiles.bat");
     psi.RedirectStandardOutput = true;
     psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
     psi.UseShellExecute = false;
     System.Diagnostics.Process listFiles;
     listFiles = System.Diagnostics.Process.Start(psi);
     System.IO.StreamReader myOutput = listFiles.StandardOutput;
     listFiles.WaitForExit(2000);
     if (listFiles.HasExited)
      {
      string output = myOutput.ReadToEnd();
      this.processResults.Text = output;
     }
    }

    Example 3. Displaying a URL using the default browser on the user’s machine:

    private void launchURL_Click(object sender, System.EventArgs e){
     string targetURL = @http://www.duncanmackenzie.net;
     System.Diagnostics.Process.Start(targetURL);
    }

    In my opinion, you are much better off following the third example for URLs, as opposed to executing IE with the URL as an argument. The code shown for Example 3 will launch the user’s default browser, which may or may not be IE; you are more likely to provide the user with the experience they want and you will be taking advantage of the browser that is most likely to have up-to-date connection information.
    C# code download available from http://www.duncanmackenzie.net/Samples/default.aspx
    By the way, this post is a simple port of an earlier VB FAQ post… just in case you thought you had seen it already in your feeds…

  • How do I cast a string to an int, float, double, etc?

    You can use the Convert class or the Parse method of the built-in type you are casting to. i.e.

        string myStr = "123";
        int myParsedInt = Int32.Parse(myStr);
        int myConvertedInt = Convert.ToInt32(myStr);

    This example uses the int type, but you can also use the same techniques for any of the other integral or floating point types.
    [Author: Joe Mayo]

  • How are return values from a delegate handled?

    Q: How are multiple return values from a delegate handled?
    In C#, it’s possible to write a delegate such as:
    delegate double GetResult(params double p);
    If there is more than one method on this delegate, there are multiple return values.
    A: In this situation, the return value is the value that is returned from the last delegate.
    If you want more control on this, you can call GetInvocationList() on the delegate, which will allow you to call each method individually, and process the double values appropriately.
    [Author: Eric Gunnerson]
  • Why don’t nullable relational operators return bool? instead of bool?

    Q: Why don’t nullable relational operators return “bool?” instead of “bool“?
    Nullable types are a new feature of C# 2.0.
    When dealing with nullable types, if you write the following:
    int? i = 15;
    int? j = 16;
    the type of
    i == j
    is a normal bool, rather than a bool? (ie nullable bool). Why?
    A: In our initial designs, we spent a fair amount of time discussing what the behavior should be here, and how we should cross over from the three-valued nullable world to the two-valued “normal C#“ world.
    Consider the following method:
    void Process(int? p)
    {
    if (p == null)
    {
    // do some processing…
    }
    }
    This seems like a very natural thing for a C# user to want to write. But if equality is three-valued, comparing anything to null always returns a null value (ie null isn’t equal to anything), and therefore such a comparison can never succeed. Instead, the user would have to write:
    if (!p.HasValue)
    or something similar. We decided that the value of having a model that was consistent with the way users were used to dealing with reference null was pretty high, and therefore decided to make the relational operators return bool.
  • Why can’t I use the same variable as an inner loop does?

    Q: Why can’t I do the following:
    namespace Bug

    {

    class Class1

    {

    [STAThread]

    static void Main(string[] args)

    {

    for(int i=0; i<100; i++)

    {

    }

    int i = 0;

    }

    }

    }

    the compiler gives me an error on the “int i = 0;” part of the code.
    A: This is correct behavior, and is covered in section 3.7 of the language spec. It says, “The scope of a local variable declared in a local-variable-declaration (8.5.1) is the block in the which the declaration occurs”.
    The scope of i is therefore the entire Main() function, and that means that the use in the for loop is a re=use, and therefore is not allowed.
    This behavior is inteded to make incorrect re-use of variable names (such as in a cut and paste) less likely.
    [Author: Eric Gunnerson]

  • How do I write a method that accepts a variable number of parameters?

    Q: How do I write a method that accepts a variable number of parameters?

    A: Languages like C and C++ have always offered some means for using and creating functions capable to accept a variable number of parameters. The most widely known example of a function which takes a variable number of parameters is printf():

    int printf(char *format, …); // the ellipsis means variable number of params

    Using this function is pretty easy:

    printf(Hello, world\n);

    printf(The sum of %d and %d is %d\n, a, b, a+b);

    However, the creation of such functions in these languages relays on a set of predefined macros and is not particularly elegant or intuitive.

    C# offers an elegant solution to this problem through parameter arrays. A parameter array is a single-dimensional array included as the last parameter in the parameter list of a method:

    public string Concat(string separator, params string[] strings)

    {

    string result = “”;

    for (int i = 0; i < strings.Length; i++)

    {

    if (i > 0)

    result += separator;

    result += strings[i];

    }

    return result;

    }

    Such a function can be called in two different ways:

    a) Passing the function an array instance argument:

    string[] names = { “Anders”, “Eric”, “Scott”, “Duncan” };

    MessageBox.Show(Concat(“+”, names) + ” = great team”);

    b) Using zero or more type-compatible arguments for the parameter array:

    MessageBox.Show(Concat(“+”, “Anders”, “Eric”, “Scott”, “Duncan”) +

    ” = great team”);

    In this case, the invocation will create an array from the supplied arguments and use it as the actual argument.

    Thanks to the unified .NET type system, object[] can be used as “common denominator” for arguments of different types:

    public int SumTheIntegers(params object[] list)

    {

    // sum all the integers included in list

    int sum = 0;

    foreach (object o in list)

    if (o.GetType() == typeof(int))

    sum += (int) o;

    return sum;

    }

    [Author: Octavio “Dave” Hernandez]

  • Why doesn’t C# support static method variables?

    Q: In C++, it’s possible to write a static method variable, and have a variable that can only be accessed from inside the method. C# doesn’t provide this feature. Why?
    A: There are two reasons C# doesn’t have this feature.
    First, it is possible to get nearly the same effect by having a class-level static, and adding method statics would require increased complexity.
    Second, method level statics are somewhat notorious for causing problems when code is called repeatedly or from multiple threads, and since the definitions are in the methods, it’s harder to find the definitions.
    [Author: Eric Gunnerson]
  • Why must attribute properties be read/write in C#?

    Q: Why must attribute properties be read/write in C#?
    In the C# language, when you define an attribute class, you can define both constructor arguments and properties. For example:

    class MyAttribute: Attribute
     {
         string name;
         int number;
         public MyAttribute(string name) { this.name = name;}
         public int Number
         {
             get {return number;}
             set {number = value; }
         }
         public string Name
         {
             get {return name;}
         }
     }
     [My("Fred", Number=5)]
     class Fred
     {
     }

    When you do this, C# requires that properties (such as Number in this example) be read/write properties, though languages such as VB.NET only require them to be readable.
    Why?
    A: Using an attribute in C# is logically equivalent to calling the constructor of the attribute class, and then executing the “property = value” part for each named property. Requiring a writeable property is consistent with this view.
    Author: Eric Gunnerson

  • Why do I get the error “Object reference not set to an instance of an object”?

    The code is trying to access a member of a reference type variable that is set to null.
    Given the following class, let’s examine some code that could be in the Main method:

    using System;class Foo
     {
      static void Main()
      {
       // foo has not been instantiated
       Foo foo = null;
    
    // implementation to be discussed...
      }
    
    public int BarProperty
      {
       get { return 0; }
      }
    
    public string BarMethod()
      {
       return null;
      }
     }

    Looking at Main, notice that foo is set to null. Your situation will not be this explicit because the variable you are trying to use could be a class field, parameter, or local variable that was once instantiated but was subseqently set to null. Given that foo is null, the following code will throw a NullReferenceException:

      try
       {
        // foo is null, and you can't call
        // BarProperty on null.
        int resultBad = foo.BarProperty;
       }
       catch (NullReferenceException nre)
       {
        Console.WriteLine(
         "\nCan't read BarProperty, foo is null.\n" +
         nre.Message);
       }

    Since foo is null, you can not use its members. This was a property, but the following code demonstrates calling a method:

      try
       {
        // foo is null, and you can't call
        // BarMethod on null.
        foo.BarMethod();
       }
       catch (NullReferenceException nre)
       {
        Console.WriteLine(
         "\nCan't call BarMethod(), foo is null.\n" +
         nre.Message);
       }

    The code above throws a NullReferenceException because foo is still null. It doesn’t matter that the first call was a property and the second is a method – they are both members of the type.
    Now, to fix this problem, you must ensure that foo is instantiated before it is used. The following code instantiates foo and the previous problems are solved:

      // now we have an instance
       foo = new Foo();  // works fine
       int resultGood = foo.BarProperty;

    Since foo now refers to a valid instance, the code can call any of its members. This was easier than many null reference problems. Sometimes you have multiple levels of indirection, leaving you with a scenario you didn’t expect. Assuming that foo now references an object, there is still a problem with the following code:

      try
       {
        // still breaks because BarMethod() returned
        // null and you can't call Trim() on null.
        foo.BarMethod().Trim();
       }
       catch (NullReferenceException nre)
       {
        Console.WriteLine(
         "\nCan't call Trim(), BarMethod() returns null.\n" +
         nre.Message);
       }

    The problem occurs in the code above because BarMethod returned null, which means that the code is trying to call the Trim method on a string reference that is set to null.
    The proper way to fix this problem is to debug BarMethod to find out why it returned null. That assumes BarMethod is not supposed to return null. If, in your application, it made sense for BarMethod to sometimes return null, then you would have to check the return value of BarMethod before you called any members of the return value.
    [Author: Joe Mayo]

  • Why did I receive the error: “The type or namespace ‘<namespace name>’ does not exist in the class or namespace ‘<parent namespace>’ (are you missing an assembly reference?)”

    You need to add a reference in your project to an assembly where that namespace is defined.
    If you are using VS.NET:
    1. Right click on the References folder on your project.
    2. Select Add Reference.
    3. Select the .NET tab (or select the Browse button if it is not a .NET Framework assembly).
    4. Double-click the assembly containing the namespace in the error message.
    5. Press the OK button.
    If you are using the command line, use the /r: or /reference: option. For Example:
    csc.exe /reference:System.Drawing.dll MyFontDisplayApp.cs
    When you recompile, this error will no longer appear.
    You can find the assembly, where a namespace is defined, in the documentation. Identify one of the types in the namespace that you want to use. Every type in the .NET Framework has an “About” page that provides an overview, basic information about the type, and example code if you’re lucky. At the bottom of the Overview, for all types, there is a “Requirements” section. This has a Namespace member that tells what namespace the type belongs to. It also tells what assembly type belongs to, which is the assembly you need to reference in your application. For example, if I had an application that was using Font types, I would look up Font in the .NET Framework documentation, using the Index tab, and observe that the Font type is in the System.Drawing namespace and its assembly is System.Drawing.dll.
    Another question related to this is “If I’ve already declared a using statement, why do I have to add the reference to the project?”
    The reason derives from the fact that the using statement and assembly references have two different purposes. Recall that the purpose of namespaces is to disambiguate type references and provide logical organization of types. When specifying a namespace in a using statement, you are telling C# that you want to use the types in that namespace in an unqualified manner. The key point is that namespaces are “logical” entities that could exist in one or more assemblies. On the other hand, assemblies are “physical” entities that contain multiple types. Assemblies are many things, but for the purposes of this discussion, an assembly is the unit of deployment in .NET. So, the reason you need a reference to the assembly that the type is located in is so that C# can find the physical location of that type, which is not possible with the logical namespace provided by a using statement.
    [Author: Joe Mayo]
  • How can I subscribe to events exposed by a remoted object?

    Delegates require information about the type that the method is associated with in order to make a call. In a single app-domain, this isn’t a problem, because the server (the object firing the events) has access to the type information for the client (which has the event handlers) by way of the delegate.
    However, during remoting, the server most likely does not have any information about the client. If you want events from the server to fire in the client app domain, then the client must derive from MarshalByRefObject. This is required so that the server will call back into the client, as opposed to a copy of the client object that is passed to the server.
    A simple way to do this is to place a copy of the client assembly in the same directory where the server directory is. While this will work, it is not an elegant solution, as it exposes the client type unecessarily.
    A more elegant solution (albiet more complex), is to have a single assembly that is referenced by both the client and the server. This assembly will have a shim class which will expose methods that share the signature of the events that you want to shim. The assembly will also provide an interface with methods that share the signature of the events as well. The shim will then take a reference to the interface, and the methods will aggregate the call to the interface that was passed in (I recommend the constructor as the place to pass the interface implementation).
    Finally, the client object will implement the interface. When subscribing to the events that the server exposes, attach the delegates to the methods on the shim, which will be passed your client object’s implementation.
    It is also important to note that in order for this to work, the TypeFilterLevel property on the sink provider for the server needs to be set to TypeFilterLevel.Full.
  • Why does my Windows Form project not use visual styles in XP even when I call Application.EnableVisualStyles?

    If you set a property on a Windows Forms control which forces the creation of the control (e.g. the SelectedIndex property on the ComboBox class), the control (and perhaps the rest of the form) will not render with visual styles enabled.
    The resolution is to place the code that sets these properties in an event handler for the Load event on the form/control.
  • Why aren’t reference types polymorphic?

    Q: Why aren’t reference types polymorphic?
    A: Consider the following code:

    using System;
    class Dog {
       public string Name;
    }
    
    class Test
    {
       public static void Swap(ref object a, ref object b) {
          object temp;
          temp = a;
          a = b;
          b = temp;
       }
    
    public static void Main() {
           Dog d1 = new Dog();
           d1.Name = "fido";
           Dog d2 = new Dog();
           d2.Name = "rex";
           Swap(ref d1, ref d2);
        }
     }

    The compiler will report an error on the call to the Swap() function. Why? Consider if the swap function was like this:

       public static void Swap(ref object a, ref object b) {
    
    a = 5;
    
    b = “Hello“;
    
    }

    If the compiler allowed this code, it would mean assigning a boxed int to a Dog object, which is clearly not type safe.
    [Author: Eric Gunnerson]

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s