DanVallejo's WebLog
view rss
C# 2.0 Generic Interfaces
14/10/2004 external link
Just as in generic classes, it is useful to define generic interfaces. It's useful to define generic interfaces for collections such as linked lists. In this example, we are defining a generic interface that requires T to be a reference type.// File: GenericInterfaces.csusing System;public interface INode<T> where T:class{    string Value    {        get;    }    T Next    {        get;    }}public class PersonNode : INode<PersonNode>{    private string name;    private PersonNode next;    public PersonNode(string name, PersonNode next)    {        this.name = name;        this.next = next;    }    public string Value    {        get        {            return name;        }    }    public PersonNode Next    {        get        {            return next;        }    }}public class Program{    static void Main()    {        PersonNode danNode = new PersonNode("dan", null);        PersonNode sabetNode = new PersonNode("sabet", danNode);        PersonNode mikeNode = new PersonNode("mike", sabetNode);        PersonNode node = mikeNode;        while (node != null)        {            Console.WriteLine(node.Value);            node = node.Next;        }        Console.ReadLine();    }}
C# 2.0 Constraints on Generic Types
14/10/2004 external link
You can also set up constraints on generic classes. What if you wanted to create a generic list of objects that derived from a certain base class? This would allow you call certain functions that existed in that class. By constraining the type, you increase the number of functions you can perform on the type. // File: Constraints.csusing System; public class Employee{    private string name;    private int id;     public Employee(string name, int id)    {        this.name = name;        this.id = id;    }     public string Name    {        get         {             return name;         }        set         {            name = value;         }    }    public int Id    {        get         {            return id;         }        set         {            id = value;         }    } } class MyList<T> where T : Employee{    T[] list;    int count;    public MyList()    {        list = new T[10];        count = 0;    }     public void InsertSorted(T t)    {        int index = 0;        bool added = false;         while (index < count)        {            if (list[index].Id > t.Id)            {                for (int last = count; last > index; last--)                {                    list[last] = list[last - 1];                }                list[index] = t;                added = true;                break;            }            index++;        }         if (!added)        {            list[index] = t;        }        count++;    }} class Program{    static void Main()    {        MyList<Employee> myList = new MyList<Employee>();         myList.InsertSorted(new Employee("dan", 200));        myList.InsertSorted(new Employee("sabet", 100));        myList.InsertSorted(new Employee("mike", 150));        myList.InsertSorted(new Employee("richard", 120));    }} Constraint Description where T: struct The type argument must be a value type where T: class The type argument must be a reference type where T: new( ) The type argument must have a public default constructor where T: <base class name> The type argument must be the base class name or derived from the base class name. where T: <interface name> The type argument must be the interface or implement the interface. Multiple interfaces may be specified.
C# 2.0 Generics
14/10/2004 external link
Visual Studio 2005 also introduces the next version of C#. C# 2.0 introduces generics, iterators, partial class definitions, nullable types, anonymous methods, the :: operator, static classes, accessor accessibility, fixed sized buffers (unsafe), friend assemblies, and #pragma warnings. Generic types allow for the reuse of code and enhanced performance for collection classes (due to boxing and unboxing issues). Generics are classes that are not type specific. For example, instead creating a Stack class for integers, another one for floats, you can create a generic class. The way this was done in the past was to create classes that just took objects. But, this lacks compile-time type checking. Everything is done at run-time.// File: StackObject.csusing System;class Stack{    object[] stack;    int top;    public Stack(int size)    {        stack = new object[size];        top = 0;    }    public object Pop()    {        return stack[--top];    }    public void Push(object v)    {        stack[top++] = v;    }}class Program{    static void Main()    {        Stack stack = new stack(10);        // Performance hit, boxing!!!        stack.Push(5);        stack.Push(10);        // Another perf hit, unboxing!!!        int top = (int)stack.Pop();    }} By using generics, you can eliminate the boxing and unboxing.// File: StackGeneric.csusing System;class Stack<T>{    T[] stack;    int top;    public Stack(int size)    {        stack = new T[size];        top = 0;    }    public T Pop()    {        return stack[--top];    }    public void Push(T v)    {        stack[top++] = v;    }}class Program{    static void Main()    {        Stack<int> intStack = new Stack<int>(10);        intStack.Push(5);        intStack.Push(5);        int top = intStack.Pop();    }}  
Test Driven Development
14/10/2004 external link
If you go up to http://www.msdn.com/express it takes you to the beta versions of the Express skus. It has some cool features that help out in doing Test Driven development. For example, when you have an open file of a project a refactor menu option shows up. The Extract Method... option is used to extract out code from a function. Visual Studio will look at the variables used in the code block and create a new method based on the required data. Be careful to not include code that contains break or continue statements. The Rename... option is used to rename all occurences of the selected variable/function/property/etc to a new name. The Preview Changes dialog shows you the changes that are about to be made. It also verifies the changes by compiling the code as well. All the code changes are highlighted. This ensures that existing code doesn't break. The Encapsulate Field... option is used to convert a public field into a public property. Make sure the public field is lower-case before you do this. Otherwise, you will need to name the property something else. The Extract Interface... option is used to create an interface based on public functions and properties. It will also mark the class as implementing the interface. The Promote Local Variable to Parameter option is used to convert a local variable into a parameter. It will also change all calls to the function based on the assigned value of the local variable. The Remove Parameters... will change all calls to the function to no longer pass the parameter. The Reorder Parameters... will change all calls to the function to use the new ordering. Note: The Refactor Menu only shows up when a project or solution is open. I'll talk about C# 2.0 features next ...  
Heads Down on Express Skus
30/7/2004 external link
I've been heads down investigating fixes for the Express skus. I want to thank everyone for their help in assisting me. I've emailed many of you to get more information. We are making changes to make the Express skus more robust when downloading the large packages. The changes have been based on the Watson data that has been sent in. We've been really exciting about the Watson data because it's the first time that we (the Setup team) have used it. And it is driving changes into the product based on your feedback. Please keep on sending more data! Thanks!
Express Download Failure Investigation
2/7/2004 external link
I'm currently investigating the source of the download failures for the Express skus. Our number one problem is that we are seeing timeout problems. Unfortunately, that could be caused by many factors, including just Internet problems. Please contact me. I will return every message posted to me. Thanks! -Dan Vallejo, Setup Dev Team
Microsoft Visual C# 2005 Express Edition Beta Setup
2/7/2004 external link
We finally put the Express skus up on the web. Our first attempt was on Wednesday at midnight. We've been working on making our setups downloadable. We use the BITS technology to download the files and then install them. One of the major reasons for using BITS is to facilitate the downloading of large files. In total, we download around 250 megs of data. And given how finicky the Internet is, it can easily fail. BITS is designed to help out. Our first problem is that we set our timeout values too low. We BITS gets a failure we wait for a maximum of 30 seconds. This, as we found out, is too small. Within a few hours of posting the Beta Express skus we got information back from Watson and user reports that timeouts were our biggest cause of failures. We scrambled to figure out how to fix the problem. Which as it turned out was just tweaking a couple of constants. So our second attempt went up sometime Wednesday night. I installed the second version on Tuesday night from a private drop. BE PATIENT it may look hung but it's not. So when I started the installation, it downloaded all the packages. This takes a while. In fact, my install sat at 279091 K for about 10 minutes. I guess the new timeout values worked because it kept waiting and eventually continued. I already have Visual Studio 2002 installed on my machine so after it installed the .NET Fx 2.0, it rebooted. Here's where the fun happened. After the reboot, it continued but it look hung. The installation progress bar was at 100% and all the packages where checkmarked. Also, all the packages where in alphabetical order. This is the bug. As long as the hard drive light is going, which mine was, it's fine. It will take another 30 minutes or so depending on your machine to finish installing the rest of the packages. It worked on my machine! Let me know if you have any questions. --Dan VS Setup Team
Serial Programming in Whidbey
25/5/2004 external link
I saw Brad's blog on Serial Programming in Whidbey. It made me think about the days when I used to communicate with BBS's on a 2400 baud modem. I saw one of the C# serial demo projects required an LCD display from Crystalfontz. I went ahead and ordered the 632 with 16x2 display. Should be here soon...
TechEd 2004 - San Diego
25/5/2004 external link
Balmer gave the keynote address to a packed crowd. He brought up the mission of doing more with less. Our industry along with education and healthcare have the chance to change people's lives. Everyone in our field has that opportunity. There are so many ways in which we can truly make a difference. .NET is becoming more prevalent. Take a look at Visual Studio, Windows Server 2003, Longhorn, Office, Yukon (next version of SQL), and so on. The list of .NET compatible products is increasing. Microsoft is really making a big bet and a programming shift into .NET. We're also betting on Visual Studio 2005 Team System (Burton). This is our end-to-end solution for developing a product. It will allow you to manage a product from specification, to bug tracking, to stress testing, and so on. A lot of cool things are happening. --Dan I received this information by one of program managers, Kevin Morrill, attending the conference.
Getting an Interface Object
22/5/2004 external link
You have several ways of getting an interface object. The implicit way has the advantage in that the compiler makes sure that the interface is implemented by the class. The disadvantage is that someone reading your code won't know that this is an interface being torn off. This just might need some more comments, that's it. The explicit way has the advantage in that you have exactly called out the interface name. The problem is that you won't find out until runtime whether the code actually works or not. An exception will be thrown if the conversion is not able to take place. The explicit way with the "as" has the advantage of being able to check if the interface is implemented similar to what was discussed above. Keep in mind that when you use the "as" method then you should be checking for null.static void Main() { Tester tst = new Tester(); IReader reader;    // implicit compile-time conversion    reader = tst;         // explicit run-time conversion with exception    reader = (IReader)tst;    // explicit run-time conversion with null    reader = tst as IReader;}
Creating Datatips for Debugging Your Classes
22/5/2004 external link
How do you display the contents of your custom classes. When you hover over a variable in the debugger, it shows you the contents of the variable. How do you do that for your own classes? In the directory C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger, there is a file named mcee_cs.dat that contains the various definitions for how they should display in the debugger. Add the following line to the mcee_cs.dat file:<yourNameSpace.yourClassName>=V1=<memberVar1> V2=<memberVar2> You'll first need to shut down Visual Studio and then when you debug the program you can hover over the custom classes and see their contents.
Events versus Delegates
22/5/2004 external link
So what is the difference between events and delegates? The reality is that currently they are basically the same. The difference is that the += operator that is used to add a delegate function to an event is thread-safe whereas when using a delegate the += operator is not thread-safe. events have always been multi-cast, meaning that an event might call multiple functions. In the beta version of .NET delegates where single-cast meaning that only a single delegate function would be called. But in the RTM version of .NET 1.0, delegates were made multi-cast. If you look at the MSIL you'll see more differences. But in general, you can simply remove the event keyword and your program for the most part will work the same as it did. The main usefulness that I see is that it indicates to the user what your intentions are. A delegate is simply a function pointer that can be used to call custom code such as passing in the comparison function. An event is used to notify the user that a special event has happened such as new mail has arrived.
Implementing Properties on an Interface
22/5/2004 external link
When you implement an interface that has a property. You would think that you wouldn't be able to add additional accessors. Given the IDisplay interface below then class should only be allowed to implement the set accessor. But in reality since properties really resolve down to just functions, all you are really doing is just adding another function to your class. So you can actually implement the interface property with both the get and set accessor even though the propery is only supposed to have the set accessor. interface IDisplay{    string Message    {        set;    }}    class Shape : IDisplay{    public string Message    {        get // not part of the interface        {            return msg;        }        set        {            msg = value;        }    }} Note: That this ONLY works when you use public interface implementation if you switch this to explicit interface implementation then you get a compiler error. class Shape : IDisplay{    string IDisplay.Message    {        get // syntax error        {            return msg;        }        set        {            msg = value;        }    }}
Explicit Implementation of Multiple Interfaces
22/5/2004 external link
If you have interfaces derived from other interfaces it makes explicit implementation of them a little funny in the class. Notice that in the following code (class TestBar) when you implement IBar that you need to use IFoo even though the class only indicates that it's implementing IBar. interface IFoo{    void Draw();} interface IBar : IFoo{    void GetString();}    class TestBar : IBar{    void IFoo.Draw()    {    }    void IBar.GetString()    {    }}
Creating Charts in ASP.NET
4/8/2003 external link
I finished my first pass at the Advanced ASP.NET course. Here's a snippet of my section on graphics... Add a new web form named Chart.aspx. Modify Page_Load as follows: private void Page_Load(object sender, System.EventArgs e) { Random r = new Random(); // A. Create a bitmap object Bitmap bmp = new Bitmap(250,150); // B. Create a graphics object to draw on // based on the bitmap. Graphics g = Graphics.FromImage(bmp); // C. Draw on the graphics object g.FillRectangle(new SolidBrush(Color.Beige), 0,0, bmp.Width, bmp.Height); SolidBrush b = new SolidBrush(Color.Navy); Font f = new Font("Arial", 14); Font legend = new Font("Arial", 6); for (int x = 0; x < 10; x++) { int h = r.Next(1,100); // rectangles fill upside down g.FillRectangle(b, x*20, bmp.Height - h - 10, 15, h); g.DrawString((x+1).ToString(), legend, b, x*20, bmp.Height - 10); } g.DrawString("Hello World", f, new SolidBrush(Color.Red), 10, 10); // D. Save the bitmap to the response outputstream bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif); // E. Dispose of the objects g.Dispose(); bmp.Dispose(); } Press F5 and navigate to the Chart.aspx page Now how do you include the chart in another page? Open Default.aspx and drag an Image control on the bottom of the page. Modify the ImageUrl property to Chart.aspx. Press F5. Pretty cool!