Sunny Ahuwanya's Blog

Mostly notes on .NET and C#

Exploring C# 6

C# 6, the latest version of the C# programming language, is here and is (almost) feature complete.
In this post, we'll explore the new language features interactively. Let's start with the most fun feature.

Using Static

using static System.Console;
using static System.Tuple;

WriteLine(Create("C#", 6));

//Hit Go to run this code


Using static lets you import static members of types directly into scope.
In the above example, WriteLine is imported from the System.Console type and Create is imported from the System.Tuple type.
This feature is useful if you frequently use a group of static methods.

Using static also lets you import static members of non static types, including structs and enums.

using static System.String;
using static System.DateTime;
using static System.DayOfWeek;

Concat("Is today a ", Monday, " or a ", Tuesday, " ? : ", Now.DayOfWeek == Monday || Now.DayOfWeek == Tuesday)


In the example above, Concat is imported from the non-static System.String class, Monday and Tuesday are imported from the System.DayOfWeek enum and Now is imported from System.DateTime.

When you import a namespace, you bring into scope all visible types and all extension methods in the namespace.
With using static, you can now import extension methods from a single class.

using static System.Xml.Linq.XDocument;
using static System.Xml.Linq.Extensions;

var cities = Parse(
@"<Root>
    <State name='California'>
        <City name='Los Angeles' />
        <City name='San Francisco' />
    </State>
    <State name='New York'>
        <City name='New York City' />    
    </State>
</Root>").Descendants("City");

cities.AncestorsAndSelf()


In the example above, Parse is imported from the XDocument class and AncestorsAndSelf is imported from the System.Linq.Extensions class.
This code is able to use the extension methods in the System.Linq.Extensions class without bringing all types in the System.Xml.Linq namespace into scope.

 

nameof expressions

Occasionally, you need to supply the name of a variable, type, type member or other symbol in your code. A common example is when throwing an ArgumentNullException and the invalid parameter needs to be identified.

In the past, you would have to use reflection to find the name, which is a bit tedious, or hardcode the name, which is error prone.
nameof expressions validate and extract the name of the symbol as a string literal at compile time.

void MyMethod(string input)
{
    Console.WriteLine(nameof(input));    
    if (input == null) throw new ArgumentNullException(nameof(input));
}

MyMethod(null);


In the above example we're able to throw an ArgumentNullException specifying the name of the erring parameter without hardcoding its name.
If the parameter name is changed in the future via a refactoring operation, the new name will be reflected in the thrown exception.

nameof expressions work on different kinds of code symbols.

string s  = "a string";

//On an instance variable of a type
Console.WriteLine( nameof(s) );
//On a dotted member of the instance
Console.WriteLine( nameof(s.Length.ToString) );
//On a dotted member of a type
Console.WriteLine( nameof(Console.Write) );

In each case in the example above, the name of the last identifier in the expression is extracted.

 

Null-conditional operators

Null-conditional operators let you evaluate members only if a null resolution was not reached in the evaluation chain.

string s = null;

int? length = s?.Length;
Console.WriteLine(length == null);

//In an indexer/element access
char? firstChar = s?[0];
Console.WriteLine(firstChar == null);


As seen in the example above, this eliminates the need to write code that checks for null on each member access.
Null-conditional operators can be chained.

string GetFirstItemInLowerCase(IEnumerable<string> collection)
{
    return collection?.FirstOrDefault()?.ToLower();
    
    /*
    //Pre C# 6 code:
    if(collection == null || collection.FirstOrDefault() == null) return null;
    return collection.First().ToLower();
    */    
}

GetFirstItemInLowerCase(new string[0])


The method above returns the first item in a collection of strings in lower case.
It returns null if the collection is null or the collection is empty or the first item in the collection is null.

Null-conditional operators make the code more succinct than the pre-C# 6 code.

The null-conditional operators work with the null coalescing operator ( ?? ) to provide a default result when the expression evaluates to null.

string[] arr = null; //new string[]{"paper","pen"};
int length = arr?[0]?.Length ?? -1;

length


In the example above, length is -1 because the null-coalescing operator provides a default value.
Replace arr = null; with arr = new string[]{"paper","pen"} to get the length of the first element.

 

String Interpolation

String interpolation lets you format strings in an easier and safer manner.

var now = DateTime.Now;

var msg = "Have a happy \{now.DayOfWeek}! Today is day \{now.DayOfYear} of \{now.Year}";
/* //Same as:
var msg = String.Format("Have a happy {0}! Today is day {1} of {2}", now.DayOfWeek, now.DayOfYear, now.Year);
*/

msg


In the example above, the now.DayOfWeek, now.DayOfYear and now.Year expressions are placed exactly where they will appear.
You can now safely modify the string without worrying if the arguments at the end line up properly as is the case when String.Format is used.

The syntax of this feature will change in a later release so that the interpolated strings are composed like this:
var msg = $"Have a happy {now.DayOfWeek}! Today is day {now.DayOfYear} of {now.Year}";

I'll update this post once that change is made.

 

Parameterless constructors in structs

Structs can now have parameterless constructors.

struct Point
{
    public int X {get; set;}
    public int Y {get; set;}
    public int Z {get; set;}
    
    public Point()
    {
        X = -1;
        Y = -2;
        Z = -3;
    }
}

new Point()


This feature is useful if you need to create a new instance of a struct with a parameterless constructor that initializes fields to values that are not the default type value.

Consider a generic method that returns a list of a generic type.

public List<T> CreateList<T>(int count) where T:new()
{
    List<T> list = new List<T>();
    for(int i = 0; i < count; i++)
    {
        list.Add(new T());
    }
    
    return list;
}

struct Point
{
    public int X {get; set;}
    public int Y {get; set;}
    public int Z {get; set;}
    
    public Point()
    {
        X = -1; Y = -2; Z = -3;
    }
}

CreateList<Point>(3)


Calling CreateList<Point>(50) in older versions of C# will return a list of 50 Point objects, however, each point will be invalid since the X,Y and Z properties will default to zero.
With C# 6, all points in the list will have the desired initial values for X, Y and Z.

There is a bug in this feature and it doesn't currently work quite as expected.

 

Expression bodied methods and properties

This feature lets methods and properties have bodies that are expressions instead of statement blocks.

public string Hexify(int i) => i.ToString("X");

/* //Same as:
public string Hexify(int i)
{
    return i.ToString("X");
}

*/

Hexify(7012)


The body of the Hexify method above is expressed as an expression, like a lambda expression, and is equivalent to the commented out regular style body.
Bodies of getter-only properties and indexers can also be expressed as expressions.

class Order
{
    private Guid _id = Guid.NewGuid();
    
    public string Id => _id.ToString();
    
    /* //Same as:
    public string Id
    {
        get
        {
            return _id.ToString();
        }
    } */
}

new Order().Id

Auto-Property Initializers

Auto properties can now be initialized with an initial value.

class Order
{
    public string Instructions {get; set;} = "None";
    
    public string Id {get;} = Guid.NewGuid().ToString();
}

new Order()


A new instance of the Order class above will have the Instructions property set to "None" and the Id property set to a new Guid string.
It's important to note that the default values are initialized once on the underlying backing field. This means each call to the Id property will return the value on the backing field and not a brand new Guid.

Getter-only auto-properties can also be assigned an initial value in the type's constructor.

class Order
{
    public string Instructions {get; set;} // Okay in C# 5
    public string Id {get;} // Only okay in C# 5 if class is abstract or extern
    
    public Order()
    {
        Instructions = "None"; // Okay in C# 5
        Id =  Guid.NewGuid().ToString(); // New in C# 6
    }
}

new Order()

 

Index Initializers

This feature lets you initialize the indices of a newly created object as part of the object initializer.

var birthdays = new Dictionary<string, DateTime> {
    ["Turing"] = new DateTime(1912, 6, 23),
    ["Lovelace"] = new DateTime(1815, 12, 10),
    ["Neumann"] = new DateTime(1903, 12, 28)
};

birthdays


This feature makes it easy to compose hierarchical objects, suitable for JSON serialization.

var locations = new Dictionary<string, object>
{
    ["Canada"] = null,
    ["Mexico"] = "Distrito Federal",
    ["United States"] = new Dictionary<string, object>
    {
        ["Illinois"] = null,
        ["New York"] = "New York City",
        ["California"] = new string[]{"Los Angeles", "San Jose"}
    }
};

locations


The object above is easier to read and compose than having to assign values to indices in separate statements after each new dictionary is created.

 

Exception filters

This feature allows a catch block to execute only when some criteria is met.

int state = 3;
try
{
    throw new InvalidOperationException();
}
catch (InvalidOperationException) if (state == 2)
{
    Console.WriteLine("Exception thrown! State = 2");
}
catch (InvalidOperationException) if (state == 3)
{
    Console.WriteLine("Exception thrown! State = 3");
}
catch
{
    Console.WriteLine("Exception thrown!");
}


In the example above, the first catch block is not executed because state isn't 2, even though that catch block handles the InvalidOperationException.
The exception processing logic then moves to the next catch block which is executed because it handles the exception type and the filter evaluates to true.

This is cleaner than having a big catch block that checks the criteria within the block. An added benefit of using exception filters instead of catching and rethrowing exceptions is that it doesn't change the stack -- useful when debugging the source of an exception.

 

Conclusion

C# 6 is a nice improvement that addresses many of the annoyances C# developers face daily.
I applaud the direction in which the C# team is taking the language. I really like using static, nameof expressions, null conditional operators and string interpolation.
These features will undoubtedly make life easier for many developers.

C# Brain teasers Part II

I’ve compiled a few C# brain teasers that you can explore interactively.
They are a tougher than the ones I posted previously but are only limited to the C# 2.0 feature set, to keep things simple.

Try to guess the answer to each question and then hit Go to evaluate the code.
The explanations for the answers are at the bottom of this post.

1)

//Can you guess what the output is?

for(int i = 0; i < 10; i++)
{
    Console.Write(i + ' '); 
}

Explanation

2)

//Class declarations

class Base
{
}

class A : Base
{
    public int Field;
}

class B : Base
{
    public int Field = 0;
    public static implicit operator A(B source)
    {
        return new A { Field = source.Field };
    }
}

// Is there anything wrong with the assignment below?

A obj = new B();

// Do any of these four statements compile?

/* 1. */ object[] oArr = new string[5];
/* 2. */ A[] aArr = new B[5];
/* 3. */ object[] oArr2 = new int[5];
/* 4. */ long[] dArr = new int[5];

Explanation

3)

//Can you guess what the output is?

struct Counter
{
    int counter;
    public override string ToString()
    {
        return counter++.ToString();
    }
}

Counter c = new Counter();
Console.WriteLine(c);
Object o = c;
Object r = o;
Console.WriteLine(c);
Console.WriteLine(r);
Console.WriteLine(o);
Console.WriteLine(o);
Console.WriteLine(r);

Explanation

4)

//What is wrong with this code?

class Outer
{
    static int sField = 0;

    public class Nested
    {
        public virtual int GetFieldValue()
        {
            return sField;
        }
    }
}

class SubClass : Outer.Nested
{
    public override int GetFieldValue()
    {
        return sField + 5;
    }
}

Explanation

5)

//What is the length of the strings?

string s1 = "\U0010FADE";
string s2 = "\U0000FADE";
Console.WriteLine(s1.Length);
Console.WriteLine(s2.Length);

Explanation

6)

//What is the output? i.e. the lengths of the arrays?

int[] singleDimension = {1,2,3,4};
int[,] multiDimension = {{1,2},{3,4}};
int[][] jagged = { new int[] { 1, 2 }, new int[] { 3, 4 } };

Console.WriteLine(singleDimension.Length);
Console.WriteLine(multiDimension.Length);
Console.WriteLine(jagged.Length);

Explanation

7)

//Class declarations

class Base
{
    protected class C
    {
        public C()
        {
            Console.WriteLine("Base.C()");
        }
    }
}

class A : Base
{
    public A()
    {
        Base.C inheritedC = new Base.C();
        C myC = new C();
    }

    new class C
    {
        public C()
        {
            Console.WriteLine("A.C()");
        }
    }
}

class B : A
{
    public B()
    {
        C implicitC = new C();
        Base.C baseC = new Base.C();
    }
}

//What is outputted when a new B object is created?

B b = new B();

Explanation

8)

// What is wrong with this code?

class B
{
    private static void M() { Console.WriteLine("B.M"); }
    public static void M(int i) { Console.WriteLine("B.M(int)"); }
}

class E
{
    static void M() { Console.WriteLine("E.M"); }
    static void M(int i) { Console.WriteLine("E.M(int)"); }

    class C : B
    {
        public static void Main()
        {
            M();
        }
    }
}

Explanation

9)

//Which field initializer statement(s) in the class will not compile?

class A
{
    bool a = false;
    object b = new A();
    bool c = a;
    object d = this; 
    int j = i + 1;
    static int i = 4;   
}

Explanation

10)

//What is wrong with this code?

class Generator
{
    readonly Random rnd;

    public Generator(ref Random RandomGenerator)
    {
        GetRandomGenerator(out rnd);
        RandomGenerator = rnd;
    }

    public void Reset(ref Random RandomGenerator)
    {
        GetRandomGenerator(out rnd);
        RandomGenerator = rnd;
    }

    private void GetRandomGenerator(out Random RandomGenerator)
    {
        RandomGenerator = new Random();
    }
}

Explanation

11)

// Why won't the code below compile?

class A
{
    private int i;

    public int P
    {
        get
        {
            return i;
        }
        set
        {
            i = value;
        }
    }

    public int get_P()
    {
        return i;
    }

    public void set_P(int i)
    {
        this.i = i;
    }
}

Explanation

12)

//Why won't the code below compile?

class A
{
    int Item = 0;

    public int this[params int[] arr]
    {
        get
        {
            return Item;
        }
    }
}

Explanation

13)

//What is the output?

float number = 23, zero = 0;

try
{
    Console.WriteLine(number / zero);
}
catch (DivideByZeroException)
{
    Console.WriteLine("Division By Zero");
}

Explanation

14)

//What is the output?

//Checked context
float fMax = float.MaxValue;
int iMax = int.MaxValue;
decimal decMax = decimal.MaxValue;
checked
{
    try
    {
        Console.WriteLine(fMax += 10);
    }
    catch { Console.WriteLine("Float Overflow"); }
    try
    {
        Console.WriteLine(iMax += 10);
    }
    catch { Console.WriteLine("Integer Overflow"); }
    try
    {
        Console.WriteLine(decMax += 10);
    }
    catch { Console.WriteLine("Decimal Overflow"); }
}

//Unchecked context
fMax = float.MaxValue;
iMax = int.MaxValue;
decMax = decimal.MaxValue;
unchecked
{
    try
    {
        Console.WriteLine(fMax += 10);
    }
    catch { Console.WriteLine("Float Overflow"); }
    try
    {
        Console.WriteLine(iMax += 10);
    }
    catch { Console.WriteLine("Integer Overflow"); }
    try
    {
        Console.WriteLine(decMax += 10);
    }
    catch { Console.WriteLine("Decimal Overflow"); }
}

Explanation

15)

// Class declaration

class B
{
    public B()
    {
        M1();
    }
    public virtual void M1()
    {
        Console.WriteLine("B.M1");
    }
}

class C : B
{
    int f;

    public C()
    {
        f = 7;
    }
    public override void M1()
    {
        Console.Write("C.M2 : " + f);
    }
}

// What is outputted when a new C object is created?

new C();

Explanation

16)

// Type declarations

class MyClass
{   
    private int PrivA;
    public int PubB;
    
    public MyClass(int a, int b)
    {
        this.PrivA = a;
        this.PubB = b;
    }
}

struct MyStruct
{    
    private int PrivA;
    public int PubB;
    
    public MyStruct(int a, int b)
    {
        this.PrivA = a;
        this.PubB = b;
    }
}

// What is outputted?

MyClass c1 = new MyClass(50, 99);
MyClass c2 = new MyClass(70, 99);
MyClass c3 = new MyClass(50, 99);

MyStruct s1 = new MyStruct(50, 99);
MyStruct s2 = new MyStruct(70, 99);
MyStruct s3 = new MyStruct(50, 99);

Console.WriteLine(c1.Equals(c2));
Console.WriteLine(c1.Equals(c3));

Console.WriteLine(s1.Equals(s2));
Console.WriteLine(s1.Equals(s3));

Explanation

 

Explanations:

A1.
The output is 32333435363738394041.
A char is a numeric value that is expressed as a character so 1 + ' ' is really 1 + 32.

 

A2.
The A obj = new B() assignment is legal since an implicit conversion exists between classes A and B.

The first statement will compile because the String class derives from the Object class and so qualifies as an implicit reference conversion.
The second statement will not compile because even though there is a user defined implicit conversion, only standard implicit reference conversions are considered for arrays.
The third statement will not compile because even though Int32 derives from the Object class, it is a value type and cannot partake in an implicit reference conversion.
The fourth statement will not compile because even though the Int32 type is implicitly convertible to the Int64 (long) type, they are both value types and arrays can only convert from reference types that qualify for an implicit reference conversion.

 

A3. 
The output is:

0
0
0
1
2
3

How’s that? This is a case of boxing and unboxing turned on its head.
When the ToString() method override is called, struct c is automatically boxed to an object type to facilitate the call. This stores a copy of c on the heap and calls ToString() on that copy.
Therefore the counter field on the actual struct c never changes. The counter field for struct c will always be 0, regardless of how many times ToString() is called.

Object o is a boxed copy of struct c and object r references the same boxed copy. When ToString() is called on either o or r, the boxed copy is accessed directly and the counter is incremented.
Thus calls to o.ToString() and r.ToString() increment the same referenced counter structure.
This shows that contrary to popular opinion, it is possible, even trivial, to modify a boxed value.

 

A4.
The static Outer.sField private field is accessible to class Nested but not accessible to class SubClass because the scope of a static member includes nested classes, but it excludes subclasses of the nested class.

A5.
The output is:
2
1

The \Udddddddd escape code is used for encoding UTF-16 unicode characters (also referred to as codepoints).
System.Char structures store 16 bit values (0x0000 through 0xFFFF) and so a single System.Char is unable to store unicode characters that fall within the 0x10000 and 0x10FFFF range.
To accommodate these characters, multiple System.Char structures are used.
This is the case for string s1, where two chars are used to store the unicode character.
In string s2, only one char stores the unicode character.

String.Length returns the number of System.Char structures in the string, not the number of unicode characters.

 

A6.
The output is:
4
4

 
The Length property of arrays returns the total number of elements in single and multi-dimensional arrays.
However, it returns only the number of elements in the first dimension of a jagged array.

 

A7. 
The output is:
Base.C()
A.C()
Base.C()
Base.C()

Nested class Base.C is marked with a protected modifier and so will be inherited by classes that derive from Base. This is similar to the way protected fields are inherited, except in this case it is the access to Base.C that is being inherited.
Class A is derived from Base and so inherits access to Base.C , but also defines a nested class called C, which hides Base.C.
Base.C is still accessible from within class A but must be referred to explicitly by Base.C.
Classes that derive from class A will have access to both Base.C and A.C. However, it's important to note that external access to A.C points to the inherited Base.C because the new class A.C is implicitly private and is only visible and accessible to code within class A.
Class B is derived from class A. It inherits access to Base.C and the externally visible A.C (which is actually Base.C), so variables implicitC and baseC refer to objects constructed from the same class.

If the new class A.C's access modifier is changed to protected i.e. protected new class C , the code will output
Base.C()
A.C()
A.C()
Base.C()
because B will now inherit access to the true class A.C. In fact, since class A.C is closer to class B than class Base.C in the inheritance hierarchy, A.C can be implicitly referred to as C, and so the variable implicitC now maps to an object constructed from class A.C whereas variable baseC will refer to an object constructed from class Base.C.

 

A8.

The call to M() in the Main method is not allowed. Even though there is an accessible static M() method in the enclosing class E, the call refers to the inaccessible B.M() method because inherited members of C are preferred over members of enclosing classes.
There is an accessible inherited method M(int i), so all calls to methods named M (of any signature) from class C will be mapped to the M methods in the base class B.

It's not possible to call an overload of a method in the base class and call another overload in the enclosing class.
The compiler will choose to call either all overloads in the base class (preferably) or all overloads in the enclosing class.
If you comment out the B.M(int i) method overload, then the static M method in the enclosing class is called.

 

A9.

These two statements will not compile:

bool c = a; //CS0236 A field initializer cannot reference the nonstatic field, method, or property 'field'
object d = this; //CS0027 Keyword this is not available in the current context

Outside a method, instance fields cannot be used to initialize other instance fields.
The this keyword is unavailable outside a method, property or constructor.
Interestingly, the field A.b that initializes a brand new object A is allowed.

 

A10.

The following line will not compile:

GetRandomGenerator(out rnd); //CS0192 A readonly field cannot be passed ref or out (except in a constructor)

A readonly field cannot be passed as a ref or out parameter (except in a constructor).
Constructors can accept ref and out parameters.

 

A11.

Properties are compiled into get_{Property_Name} and set_{Property_Name} methods.
The methods get_P and set_P will conflict with the generated property methods.

 

A12.

Indexers are compiled into a property named Item and methods named get_Item and set_Item.
The field Item conflicts with the generated property name.
It’s okay to have a params modifier in an indexer.

 

A13.

The output is:
Infinity

Only integral (int, long, short, byte, uint, ulong, ushort, sbyte, char) and the decimal types throw a DivisionByZero exception when divided by zero.
Float and Double types will return special IEEE754 values such as Infinity or NaN.

 

A14.

The output is:

3.402823E+38
Integer Overflow
Decimal Overflow
3.402823E+38
-2147483639
Decimal Overflow

Overflows in integral (int, long, short, byte, uint, ulong, ushort, sbyte, char) types wrap around in an unchecked context. In a checked context they throw an overflow exception.
Overflows in floating point (float and double) types always wrap around and never throw an overflow exception in any context. They can also produce special IEEE754 values such as Infinity or NaN as results.
Overflows in the decimal type always throw an overflow exception in any context.

 

A15.

The output is:
C.M2 : 0

When C's constructor is called, It implicitly calls the base constructor before the field f assignment.
B's constructor calls the M1 method, a virtual-instance method, which resolves to method C.M1.
At the point when C.M1 is called from B's constructor, the value of field f has not been assigned yet and is the default value of zero. 

 

A16.

The output is:

False
False
False
True

By default the Equals method compares references in reference types. i.e returns true if both variables refer to the same object.
In value types, it will compare the types of the variables. If they are not the same, it returns false.
If they are the same type, it will compare the value of each field (including private ones).

Introducing C# Pad

I’m excited to present C# Pad, an interactive web based C# REPL.

Have you ever wanted to quickly evaluate an expression or test some code, like say try out different DateTime string formats or test a method or clear up some confusion (like what’s the difference between Uri.EscapeDataString and Uri.EscapeUriString or what new Random().Next(0) returns), or decode some string in Base64 or some other format?

C# Pad lets you easily do all those things and a whole lot more.

Interactive REPL

Do you see the embedded code pad below? Go ahead and hit the Go button.

var greeting = "こんにちは世界";
Console.WriteLine("{0} in Japanese is {1}", "Hello World", greeting);

After the submission is processed, you’ll see the result of the code evaluation.
Now, in the same code pad, type Console.WriteLine(greeting.Length) and hit Go.

As you can see, the greeting variable from the previous submission is accessible in the code editor.
That’s because C# Pad is a REPL. Objects in previous submissions are visible and accessible from the current one.
( Did you also notice the cool code completion? :) )

You don’t need to call Console.WriteLine to display results. Simply type the variable name (without a semicolon) in the last line of a code submission and the string representation of the variable’s value will be displayed. 
For example, type greeting in the same code pad and hit Go to see its value.

The following code pad contains a method that encodes an input string in Base64 format.

using System.IO;
using System.Text;

string Base64Encode(string input)
{
    if(input == null) throw new ArgumentNullException("input");
    
    var bytes = Encoding.UTF8.GetBytes(input);
    return Convert.ToBase64String(bytes);
}

Hit Go to submit the method and then type Base64Encode("My string") (do not include a semicolon) and hit Go.

You’ll observe the result is a string in Base64 format, encoded by the method that was defined in an earlier submission. Because the semicolon was left out, the result of the evaluation was displayed.

You can use C# Pad to write complex code, define classes and methods and evaluate all kinds of expressions ranging from simple mathematical expressions like 60 * 60 * 24 or Math.Sin((30 * Math.PI)/ 180) to LINQ expressions.

(from c in "The quick brown fox jumps over the lazy dog".ToLower()
group c by c into grp
select new { Letter = grp.Key, Count = grp.Count() }).ToArray()

C# Everywhere

You can embed interactive code pads in your blog, website or any site you can edit, just like I have in this blog post. You can even select a theme that matches your site.
Yes, this means you can now create a C# playground anywhere. Simply visit csharppad.com, compose the code you’d like to embed, click the embed button and follow the instructions.  

Here’s an example JSBin with an embedded code pad.

You can also load and save Github Gists.
To load a Gist, open csharppad.com/gist/_gist_owner_/_gist_id or simply csharppad.com/gist/_gist_id

As examples, the links below open up Gists in C# Pad.

http://csharppad.com/gist/9220821
http://csharppad.com/gist/octocat/1169852 ( Did you know The Octocat codes in C#? )

To open a single file in a Gist, append ?file_name at the end of the url, like so
http://csharppad.com/gist/9220821?random.cs

Numerical Analysis

The awesome Math.Net Numerics library is bundled with C# Pad, which makes working on complex math and statistics problems a breeze.

The following program integrates the function f(x) = exp(-x/5) (2 + sin(2 * x)) on a closed interval of [0, 100].

using MathNet.Numerics;
Integrate.OnClosedInterval(x => Math.Exp(-x / 5) * (2 + Math.Sin(2 * x)), 0, 100)


The following program generates ten samples of a Poisson distribution with a lambda parameter of 1.

using MathNet.Numerics.Distributions;
var poisson = new Poisson(1);
for(var i = 0; i < 10; i++)
{
    Console.WriteLine("{0:N05}", poisson.Sample());
}


The following program calculates the 75th percentile of an array of numbers.

using MathNet.Numerics;

var percentile = 75;
var array = new double[]{ 89.6, 33.5, 11.6, 44.3, 66.78, 34.78, 97.1, 68.0, 25.7, 48.7};

ExcelFunctions.Percentile(array, percentile / 100d)


The following program multiplies the transpose of a matrix with another matrix.

using MathNet.Numerics.LinearAlgebra.Double;

var matrixA = DenseMatrix.OfArray(new[,] { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 }, { 7.0, 8.0, 9.0 } 
});
var matrixB = DenseMatrix.OfArray(new[,] { { 1.0, 3.0, 5.0 }, { 2.0, 4.0, 6.0 }, { 3.0, 5.0, 7.0 } });

matrixA.Transpose() * matrixB

//Same as matrixA.TransposeThisAndMultiply(matrixB)

 

C# Pad is the first and only (as of this writing) web based interactive C# REPL, with code completion, diagnostics, themes, embeddability, timing information, Gist support and more features to come.

I hope you find C# Pad useful and delightful. Drop me a line or use the help link on the site to provide feedback on feature suggestions, bug reports and other kinds of feedback.

Have fun!

Exploring System.Void Part II

In my previous post, I described the role of System.Void in the .NET framework and demonstrated some of the restrictions placed on the type.
In this post, I’ll postulate why those restrictions are in place and I’ll try to bypass them in an attempt to create an instance of the type.

The restrictions on the System.Void type are documented in the Common Language Infrastructure (CLI) specification (ECMA-335)PDF Document.
I find two of these restrictions particularly interesting:

“The type System.Void is never boxable.” (Section 8.2.4)
“No location or value shall have System.Void” (Section 8.7)

Why is instantiation of the System.Void type forbidden? After all, as long as methods are not allowed to declare a return type of System.Void, the purpose of the type as discussed in my previous post remains intact, regardless of whether instances are allowed to exist or not.

So, what’s the harm in permitting instances of this type to exist? I proffer the following explanations.

Firstly, from a philosophical standpoint, it doesn’t make much sense to have the ability to instantiate a type that methods cannot declare as a return type, because that is effectively saying that you can create this object but your methods cannot pass its value (unless in a boxed representation or masqueraded as an inherited type) around.

Secondly, some unexpected issues can arise when calling methods declared in generic types. For example, if developers can instantiate System.Void, they’ll expect to be able to compile and run the following code, but by so doing produce a method that has a System.Void return type.

class Program
{
	static void Main(string[] args)
	{
		var instance = new MyClass<System.Void>().GetInstance();			
	}
	
}

class MyClass<T> where T:new()
{
	public T GetInstance()
	{
		return new T();
	}
}

The compiler/runtime can be updated to prevent such code from compiling or running, however it’s cleaner to have a rule that states that System.Void cannot be instantiated and that the expression “System.Void” is illegal anywhere in C#.

The last explanation I proffer has to do with pointers in C#, and I think it is the most functional explanation.
You can get the System.Type object of a value type pointer with the following expression:

typeof(MyStruct*)
For example:
typeof(int*)
evaluates to a System.Type object called System.Int32*

Similarly, typeof(bool*), typeof(DateTime*), typeof(char*) and typeof(System.Guid*) will evaluate to System.Type objects called System.Boolean*, System.DateTime*, System.Char* and System.Guid* respectively.

Now, there is a special kind of pointer called the void pointer which can point to any pointer type.
The type declaration for a void pointer is void*, and the following expression gets the System.Type object of a void pointer:

typeof(void*)
It evaluates to a System.Type object called System.Void*

You can already see how an ambiguity is introduced if instances of System.Void were allowed to exist.
In that scenario, typeof(System.Void*) would evaluate to a System.Type object also called System.Void*.
It would be impossible (or at least error-prone) to tell if the object is for a pointer to System.Void or for the special void pointer.

Nevertheless, and in spite of my failed attempts to instantiate System.Void in the previous post, it is possible to create an instance of System.Void -- by making it a static field.

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly ConsoleApplication1
{
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module ConsoleApplication1.exe
// MVID: {60F1E74C-3123-4EF0-8269-A0C3B8B85ADF}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00670000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       1 (0x1)
    .maxstack  8
    IL_0000:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

The IL code listing above is equivalent to the following C# program (if it were possible to compile)

class Program
{
	public static System.Void o;
	static void Main()
	{
	}
}

If I compile the IL code using ilasm and run it, I don’t observe any errors, unlike in my previous attempts.
What does this mean? Did it create an instance of the type? Is the runtime skipping over that System.Void field creation instruction? Is the program dying silently?

This is a good example of the "If a tree falls in a forest and no one is around to hear it, does it make a sound?" philosophical riddle.

What I need is some observability. I need to be absolutely sure that the type was instantiated (or not).

I’ll just modify the code a little bit to get some output:

class Program
{
	public static System.Void o;
	static void Main()
	{
		Console.WriteLine(o.ToString());

	}
}

which translates to the following IL code:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly ConsoleApplication1
{
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module ConsoleApplication1.exe
// MVID: {EE60F7FD-BD3D-46C8-B353-A459F5119496}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00260000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       22 (0x16)
    .maxstack  8
    IL_0000:  ldsflda    valuetype [mscorlib]System.Void Program::o
    IL_0005:  constrained. [mscorlib]System.Void
    IL_000b:  callvirt   instance string [mscorlib]System.Object::ToString()
    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0015:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

If I run the program, I get a fatal InvalidProgramException error message. The issue is that ToString() is defined on the base System.Object class. When I call System.Void.ToString(), the runtime boxes the value type to an object before calling the ToString() method.
Remember that rule which states that System.Void cannot be boxed. It is enforced by the runtime. There is a check that the value is not System.Void during boxing, and if the check fails, the program is halted.

On a side note, this is another good reason to avoid boxing whenever possible. There is some overhead, besides copying the value to the boxed representation, due to many type checks.

System.Void does not define any members that we can access. The other members (GetType(), ToString(), GetHashCode(), etc.) are all inherited. Calling the inherited methods will lead to boxing which is prohibited. How can we observe its existence?

There’s one way.

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly MultiVoid
{
  .permissionset reqmin
             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module MultiVoid.exe
// MVID: {AC411515-B789-4594-B52B-1EC2668D16C9}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) 
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00BC0000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .field public static valuetype [mscorlib]System.Void p
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       35 (0x23)
    .maxstack  1
    .locals init (valuetype [mscorlib]System.Void& pinned V_0,
             valuetype [mscorlib]System.Void& pinned V_1)
    IL_0000:  ldsflda    valuetype [mscorlib]System.Void Program::o
    IL_0005:  stloc.0
    IL_0006:  ldloc.0
    IL_0007:  conv.i
    IL_0008:  conv.i4
    IL_0009:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_000e:  ldc.i4.0
    IL_000f:  conv.u
    IL_0010:  stloc.0
    IL_0011:  ldsflda    valuetype [mscorlib]System.Void Program::p
    IL_0016:  stloc.1
    IL_0017:  ldloc.1
    IL_0018:  conv.i
    IL_0019:  conv.i4
    IL_001a:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_001f:  ldc.i4.0
    IL_0020:  conv.u
    IL_0021:  stloc.1
    IL_0022:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

The IL code above translates to the following uncompilable C# code:

class Program
{
	public static System.Void o;
	public static System.Void p;
	static void Main()
	{
		unsafe
		{

			fixed (System.Void* i = &o)
			{
				Console.WriteLine((int)i);
			}

			fixed (System.Void* j = &p)
			{
				Console.WriteLine((int)j);
			}

		}

	}
}

It displays the addresses of the System.Void instances in memory: If you run the IL code, you’ll see an output with the memory addresses of the two instances like as shown below:

Congratulations! You just created two instances of the forbidden System.Void type!

That may be as far as you may go. The runtime will detect attempts to place the instance on the evaluation stack, which is necessary to return the instance value from a method.

Exploring System.Void Part I

When calling a method in a dynamically created instance of a type that is discovered at runtime, it's useful to discover the types of the method parameters and the method return type. This information is needed to successfully call the method and retrieve its return value.

It's also useful to discover if the method doesn't have a return type, so that we know not to expect a return value.
One way to find out is to check if the MethodBase.Invoke call returns a null, since a dynamically invoked method that has no return type will return a null. However, this is not the best approach for the following reasons.

Firstly, any method that returns a reference type can return a null, rendering such null checks unreliable.

Secondly, this approach cannot be used to determine the return type before invoking the method.

Fortunately, MethodInfo objects have a ReturnType property that developers can inspect to determine the return type before invoking the method. For instance, if the method returns a string type, MethodInfo.ReturnType will evaluate to typeof(string). It would seem that the natural way to determine if a method does not define a return type would be to check if MethodInfo.ReturnType == typeof(null), however, that won't work because the expression typeof(null) is illegal in C#. Null is not a type.

What's needed is a specially marked type that can be used in the typeof() evaluation to determine that the method does not have a return type. Think about that for a few seconds to get a feel of how counter-intuitive that sounds.
The issue with this approach is that if a method returns an instance of the proposed special type, then the test becomes inconclusive and unreliable. To prevent this from happening, the runtime must bar creation of methods that return this special type.

Enter the System.Void structure. This type is specially designated by .NET for just this purpose. In C#, the void keyword is an alias for the System.Void structure, thus MethodInfo.ReturnType == typeof(void) is a reliable means of discovering if a method has a return type. As expected, no method is allowed to define System.Void as its return type.

This solution looks good and seems like a perfect answer to the "no return type detection" problem. However, there may be a lot more involved. C# and the CLR strangely takes it one step further by disallowing instantiation of the System.Void type by any means. Allow me to demonstrate:

Attempt 1: Try to instantiate System.Void normally

static void Main()
{
    object o = new System.Void();
    //object o = new void() is illegal in C# lingo
}
You'll get a "System.Void cannot be used from C# -- use typeof(void) to get the void type object" (CS0673) error message if you try to compile the code.

Attempt 2: Try to instantiate System.Void dynamically

static void Main(string[] args)
{

    object o = Activator.CreateInstance(typeof(void));
            
}	
It compiles, but when you try to run it, you get a "Cannot dynamically create an instance of System.Void." error message.

Attempt 3: Bypass the C# compiler, Try to create it directly from IL

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly ConsoleApplication1
{

  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module ConsoleApplication1.exe
// MVID: {47CAF74F-C24A-400E-A0F9-26EB27500120}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00D10000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       12 (0xc)
    .maxstack  8
    IL_0000:  ldsflda    valuetype [mscorlib]System.Void Program::o
    IL_0005:  initobj    [mscorlib]System.Void
    IL_000b:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

The IL code above is equivalent to the following C# code
using System;

class Program
{
	public static System.Void o;
	static void Main()
	{
		o = new System.Void();
	}
}
If you compile the IL code with ilasm, It compiles successfully, however it fails verification when you run Peverify against the compiled assembly. If you try to run the assembly, it runs into a fatal InvalidProgramException exception.
If you replace occurrences of System.Void in the IL code to any other struct in the System namespace (besides the ones that map to simple types -- they have a different syntax in IL), the IL code will compile and run smoothly.

From the examples shown above, we have established that the C# compiler and runtime prevents instantiation of the System.Void type. In my next post, We'll explore the System.Void type some more and try to figure out why the runtime doesn't want it to exist.

Happy new year!!

I Want a Native C# Compiler

Wouldn’t it be nice if C# code could be compiled directly to machine code? Having such a compiler would position C# as a serious system programming language.
Developers would be able to write system software for routers, for instance, in C#.

I don’t see any reason why such a compiler should not exist. In fact, the creation of a native C# compiler will be well justified.

C# is a well designed programming language. It would be a shame if the language is stuck forever with the .NET/Mono frameworks, especially if you consider that there is no reason why the language has to be inextricable tied to these frameworks.
There is no requirement that C# code must compile to IL and there are no language-level assumptions that the compiled code has to be machine-independent.
High-level features routinely used by developers such as threading and reflection, are .NET library calls and have no connection to the language itself. The only high-level feature that the language implies is a garbage collection system. In fact there are language-level hints that C# can be a system-level programming language -- how often do you use the volatile, stackalloc and fixed keywords?

The C# developer base is huge, so a native C# compiler will push the language even further to new platforms and projects that are currently unsuitable for development with C#. It will enable developers to write ALL their code; high-level and low-level in C#. Higher-level code will be compiled to IL, whereas lower-level code will be compiled to machine code.

A native C# compiler would be great for coding libraries, for instance, a proprietary encryption or compression algorithm. With a native C# compiler, an algorithm can be coded in C# and compiled as a native code library. This library can be linked to and used in systems without any .NET (or alternative) frameworks.
The best part is that if this library is needed for a .NET/Mono project -- all that is needed is recompilation and the algorithm will scale to managed code without having to port the library or use unmanaged calls. It will work great in both managed and unmanaged worlds.

The language is an open standard, so anyone with the time, expertise and resources can create a native C# compiler. Also, to be successful, this compiler only needs to support C# version 2.0.
Language features introduced in versions 3.0 and 4.0 are not that important and can be considered “Microsoft extensions” to the C# language. Indeed, Anders Hejlsberg admitted that features added in C# 2.0 were features they didn’t have time or didn’t know how to properly implement in C# 1.0.

If you are still not convinced about the viability of such a compiler, take a look at the compilers available for the D language. They are living proof that such a compiler is feasible and will compile a modern language directly to machine code, complete with a (small) runtime, memory management and type system.

 

C# Brainteasers Part I

Every now and then, I pick up C# Precisely by Peter Sestoft and Henrik I. Hansen, a great C# reference book that should be recommended more often.
Every time I read the text, I find bemusingly odd but very correct C# code examples.

Here are some C# brainteasers I've compiled from the book. The answers are at the end of this post.

1. What does the following code display?

class Concat
{
    static void Main()
    {
        Console.WriteLine(20 + 45 + "A");
        Console.WriteLine("A" + 20 + 45);
    }
}

Okay, that one was easy -- how about the rest?

2. What is wrong with this code?

class One
{
    sealed void SealedOnly()
    {
        // Do something
    }
    
    virtual void Virt()
    {
        // Do something
    }
}

3. What is wrong with this code?

class BaseClass
{
    public BaseClass (string Arg0)
    {
        //Do stuff       
    }
}

class DerivedClass : BaseClass 
{
    //Do more stuff
}

4. What is wrong with this code?


class Student
{
    public Student (string Name) 
    {
        //Call other constructor
        this.Student(Name, null);
    }

    public Student (string Name, DateTime? DateEnrolled)
    {
        this.name = Name;
        this.dateEnrolled = DateEnrolled;       
    }

    private string name;
    private DateTime? dateEnrolled;

}

5. What is the class access modifier for class A? how about class B?

class A
{
    class B
    {

    }
}


Answers:

1.
The code will display:

65A
A2045

This is because the + operator is left associative.


2.
The code will not compile because of errors (shown in comments) below.

class One
{
    sealed void SealedOnly() //error CS0238: Cannot be sealed because it is not an override 
    {
         // Do something
    }

    virtual void Virt() //error CS0621: virtual or abstract members cannot be private
    {
       // Do something
    }
}

You can’t have a sealed method that does not override a base method.
You can’t have a virtual or abstract method with a private access modifier.


3.
The code will not compile because of the error (shown in the comment) below.
class BaseClass
{
    public BaseClass (string Arg0)
    {
        //Do stuff       
    }
}

class DerivedClass : BaseClass // error CS1501: No overload for method 'BaseClass' takes '0' arguments (DerivedClass must explicitly call BaseClass constructor because there is no parameterless base constructor)
{
    //Do more stuff
}
This one is a bit tricky to explain. The C# compiler generates a parameterless constructor for concrete classes without any defined constructors. If there was no constructor defined for the base class, then the C# compiler will generate a parameterless constructor.
A parameterless constructor will also be generated for the derived class (since it doesn’t have any constructors) which will override the parameterless constructor for the base class.

In this case, a constructor with a single parameter was defined for the base class, so the C# compiler will NOT generate a parameterless constructor for the base class. The derived class however will have a parameterless constructor generated. The problem with the code snippet above is that the derived class’s parameterless constructor can not find a base parameterless constructor to override.

To resolve this issue, you can add a parameterless constructor to the base class, add a constructor with the same signature as the one in the base class to the derived class, or add a parameterless constructor to the the derived class with this declaration:
public DerivedClass(): base("")
{
}
This creates a parameterless constructor for the derived class which calls the base class constructor


4.
The code will not compile because of the error (shown in the comment) below.
    class Student
    {
        public Student(string Name) 
        {
            this.Student(Name, null); // error CS0117: 'Student' does not contain a definition for 'Student'
        }

        public Student(string Name, DateTime? DateEnrolled)
        {
            this.name = Name;
            this.dateEnrolled = DateEnrolled;
        }

        private string name;
        private DateTime? dateEnrolled;

    }
You cannot call constructor code using regular method access syntax, even from another constructor.
To call another constructor, use this syntax:
public Student(string Name) : this(Name, null)
{
}

5.
 A - internal
 B - private
Top-level classes without a class access modifier default to internal (and can only be either public or internal).
Nested classes without a class access modifier default to private.


Generate Stored Procedure Wrapper Methods and Associated Wrapper Classes

Introduction

It is generally a good idea to create a wrapper method for every stored procedure that an application needs to call. Such methods can then be grouped into a single data access utility class. This approach improves type safety and portability.

These methods generally call the Command.ExecuteScalar, Command.ExecuteNonQuery and Command.ExecuteReader ADO.NET methods. They also perform tasks like checking if the Connection object is still connected, adding stored procedure parameters to the Command object, making sure the DataReader object is properly disposed, etc.

On the average, there are about fifty lines of code for a properly written method that wraps an ExecuteReader call! Writing these methods easily eats into overall development time on data-intensive projects that access many stored procedures.

Developers usually resort to copying and pasting code from other wrapper methods and modifying the code to suit the stored procedure call. This process often leads to bugs due to human error.

I figured that since most of these methods share a common programming pattern; it should be possible to describe what your stored procedure looks like to a code generation tool and have the tool generate these methods. Nothing as complex as AutoSproc, just a light tool that lets a developer specify details of the stored procedure, and then generate the wrapper method code.

Implementation

This tool was developed with ASP.NET 2.0. It makes code generation decisions based on information provided by the user – pretty much the same way a human developer would make coding decisions.
It supports .NET 1.1 and .NET 2.0 features, for instance it would create nullable variables for nullable fields if .NET 2.0 is selected. It supports the SQL Server and ODBC data providers.

The actual code generation code (no pun intended) is in APP_Code\MethodGen.cs while the user interface code is in the sprocmethodgen.aspx.
The code generation code can easily be used by another application with a different user interface (for instance, a desktop-application that supplies most of the input from the actual database schema). It can also be easily modified to follow a different programming pattern or support more ADO.NET features.

The meat of the code generation code lies in the GenerateMethod, GenerateTryClause and GenerateResultsWrapperClass methods of the MethodGenerator class. The GenerateMethod method generates the non-varying parts of the method such as sections that add parameters to a command object. It also calls the GenerateTryClause method and optionally the GenerateResultsWrapperClass method.

The GenerateTryClause method generates the big try clause in the method which varies greatly, depending on what type of execution was selected.

The GenerateResultsWrapperClass method generates a class which stores results returned by a DataReader. (It’s better to return a list of strongly typed objects than returning a DataTable.)

Using the Tool

This example uses the ‘Sales by Year’ stored procedure in the Northwind database.

1) Run the ASP.NET solution, and navigate to the web page.

This tool is also available at www.ahuwanya.net/tools/sprocmethodgen/

2) Specify the .NET Version, Data Provider, Stored Procedure name, and Type of Execution.

3) The Sales by Year stored procedure has two input parameters, so specify the two input parameters:

4) After running the stored procedure, it is discovered that it has four columns in the result set, so specify the four result columns:


5) Specify the name of the class that will store the results and the name of the generated method.

6) Click the Generate Code! button to generate the code. You may need to scroll down on the page.
(To view the generated code, click the expand source button below.)

internal static List<SalesInfo> GetSalesByYear(DateTime StartDate, DateTime EndDate, SqlConnection DBConn )
{
	//TODO: Insert method into your data access utility class
	
	//Check if connection is null
	if(DBConn == null)
	{
		throw new ArgumentNullException("DBConn");
	}

	//Open connection if it's closed
	bool connectionOpened = false;
	if(DBConn.State == ConnectionState.Closed)
	{
		DBConn.Open();
		connectionOpened = true;
	}

	//TODO: Move constant declaration below directly into containing class
	const string sprocGetSalesByYear = "[Sales by Year]";

	string sproc = sprocGetSalesByYear;

	SqlCommand cmd = new SqlCommand(sproc,DBConn);
	cmd.CommandType = CommandType.StoredProcedure;
	cmd.Parameters.Add("@Beginning_Date",SqlDbType.DateTime ).Value = StartDate;
	cmd.Parameters.Add("@Ending_Date",SqlDbType.DateTime ).Value = EndDate;
	
	List<SalesInfo> result = new List<SalesInfo>();
	SqlDataReader rdr;
	
	try
	{
		rdr = cmd.ExecuteReader();

		try
		{
			if (rdr.HasRows)
			{
				int shippeddateOrdinal = rdr.GetOrdinal("ShippedDate");
				int orderidOrdinal = rdr.GetOrdinal("OrderID");
				int subtotalOrdinal = rdr.GetOrdinal("Subtotal");
				int yearOrdinal = rdr.GetOrdinal("Year");
				
				while (rdr.Read()) 
				{
					// declare variables to store retrieved row data
					DateTime? shippeddateParam;
					int orderidParam;
					decimal subtotalParam;
					string yearParam;
					
					// get row data
					if (rdr.IsDBNull(shippeddateOrdinal))
					{
						shippeddateParam = null;
					}
					else
					{
						shippeddateParam = rdr.GetDateTime(shippeddateOrdinal);
					}
					orderidParam = rdr.GetInt32(orderidOrdinal);
					subtotalParam = rdr.GetDecimal(subtotalOrdinal);
					if (rdr.IsDBNull(yearOrdinal))
					{
						yearParam = null;
					}
					else
					{
						yearParam = rdr.GetString(yearOrdinal);
					}
					
					// add new SalesInfo object to result list
					result.Add(new SalesInfo(shippeddateParam,orderidParam,subtotalParam,yearParam));
					
				}
			}
		}
		finally
		{
			rdr.Close();
		}
		
	}
	catch(Exception ex)
	{
		//TODO: Handle Exception
		throw ex;
	}
	finally
	{
		cmd.Dispose();

		if(connectionOpened ) // close connection if this method opened it.
		{
			DBConn.Close();
		}
	}

	return result;
	

}

[Serializable]
public class SalesInfo
{
	//TODO: Integrate this class with any existing data object class

	private DateTime? shippeddate;
	private int orderid;
	private decimal subtotal;
	private string year;
	
	public SalesInfo(DateTime? ShippedDate, int OrderID, decimal SubTotal, string Year)
	{
		shippeddate = ShippedDate;
		orderid = OrderID;
		subtotal = SubTotal;
		year = Year;
		
	}

	public SalesInfo()
	{
		shippeddate = null;
		orderid = 0;
		subtotal = 0;
		year = null;
		
	}

	public DateTime? ShippedDate
	{
		get { return shippeddate; }
		set { shippeddate = value; }
	}

	public int OrderID
	{
		get { return orderid; }
		set { orderid = value; }
	}

	public decimal SubTotal
	{
		get { return subtotal; }
		set { subtotal = value; }
	}

	public string Year
	{
		get { return year; }
		set { year = value; }
	}

	
}

7) Copy the generated code into your project.

8) Add the following namespaces to your project.

using System.Data; 
using System.Data.SqlClient; //if using SQL Server Data Provider
using System.Data.Odbc; //if using ODBC Provider
using System.Collections.Generic; //if using .NET 2.0 or later
using System.Collections //if using .NET 1.1

9) Look for //TODO: comments in the generated code and act accordingly. The code will still work, even if the //TODO: comments are ignored.

10) Now you can simply access the sales data from your project with the following statements:

 //Create Sql connection
SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True");
//Get Sales Information
List<SalesInfo> sales = GetSalesByYear(new DateTime(1992,1,1),new DateTime(2008,1,1),conn);

Considerations and Limitations

Obviously, this tool cannot generate code for every conceivable ADO.NET database access scenario, however, it’s a lot better to generate a great deal of the code and then modify the code as needed, than to type everything by hand.

Some limitations of this tool include:

Generates only C# code: The best way to make this tool to be language neutral would be to use CodeDom to generate the code, however, this approach would make this tool harder to maintain and extend – It would be an overkill for the scope of this project.
Fortunately, there are lots of C#-to-VB.NET code conversion tools available for VB.NET developers who would like to use this tool.

Lacks support for Output Parameters: This tool only supports input parameters and optionally returns the stored procedure return parameter. The generated code can be manually modified to accommodate other types of parameters.

Lacks support for OLEDB and Oracle Data Providers: This tool only generates code for ODBC and SQL Server Data providers.

Reads only the first Result Set: If your stored procedure returns multiple result sets, one way to handle this is to generate a method for the first result set (choose ExecuteReader), then generate another method as if the second result set were actually the first result set, copy the code that reads the result data and paste it into the first method after calling rdr.NextResults(), change the name of the results variable in the pasted code and pass it back as an out parameter.
Do this for every result set returned.

Lacks support for DbCommand object properties: If you are looking for Transaction, CommandTimeOut, CommandBehavior objects etc. -- It’s easy to modify the generated code for these properties.

Unsuitable for Large Result sets: This tool generates code which returns result sets as an ArrayList or an List of strongly-typed objects. This tool will perform poorly if your stored procedure returned hundreds of thousands of rows because it would have to store all these rows. You should write your own data access method for such scenarios.
Moreover, if your stored procedure returns hundreds of thousands of rows, I recommend you look into implementing some kind of paging mechanism to reduce the number of rows returned.