Rich Newman

June 12, 2009

Extending Classes: Extension Methods or Inheritance?

Filed under: .net, c#, dotnet — Tags: — richnewman @ 12:09 am

Introduction

Extension methods were introduced in C# 3.0 as a way of extending a class without necessarily having access to the original source code of the class.

As discussed in the C# Programming Guide on MSDN, extension methods were primarily introduced to the language to allow LINQ to add standard query operators such as GroupBy and OrderBy to any class that implements IEnumerable<T>.  This is very neat syntactically.

This article will examine how extension methods can be created and used.  It will then show one example where inheritance is probably a better approach to class extension.

Basic Usage of Extension Methods

To illustrate the basic approach to using extension methods as usual a code example is available.

This contains three projects:

  1. A ‘Core’ class library intended to represent code developed by a core group of developers and used as a library by other developers.
  2. A ‘DerivedExtended’ library that is intended to represent code extending the Core library, developed by a second group of developers.
  3. A ‘Client’ library that uses the DerivedExtended library.

Initially the Core library contains just one class with just one public property:

namespace Core
{
    public class MyCoreClass
    {
        public int CoreValue { get; set; }
    }
}

How Extension Methods Work: Writing an Extension Method

We can extend our core class in our DerivedExtended library using extension methods.  To do this clearly DerivedExtended has to reference Core.  The syntax is simple to set up an extension method:

using Core;
 
namespace DerivedExtended
{
    public static class Extended
    {
        public static void SetCoreValue(this MyCoreClass myCoreClass)
        {
            myCoreClass.CoreValue = 1;
        }
    }
}

To make this work both the class and the method in it are declared static, and we use the ‘this’ keyword on the myCoreClass parameter.  The name of the static class (‘Extended’) is not relevant for the purposes of the extension method (it’s not used to invoke it in any way).

Our extension method can only access the public interface of the class it is extending.  That is in our case it can access the CoreValue property because it is public: if it were private the extension method would not be able to set it.

How Extension Methods Work: Calling an Extension Method

We now set up client code to use this:

using System;
using DerivedExtended;
 
namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            // Instantiate the core class
            Core.MyCoreClass myCoreClass = new Core.MyCoreClass();
 
            // Call extension method
            myCoreClass.SetCoreValue();
 
            // Get property value from core class and display it
            Console.WriteLine(myCoreClass.CoreValue);
 
            Console.ReadLine();
        }
    }
}

Note the syntax for calling the SetCoreValue extension method: to the client code it looks exactly like a normal instance method on the myCoreClass instance.  Note also that we have to use ‘using DerivedExtended’ directive for the compiler to find the relevant extension method.

Clearly the code above prints ‘1’ to the console window: the extension method has set the property value as you would expect.

Why This is Fragile

Now imagine our core developers decide that they need a method to set the core value, and that the method should be setting the value to 100.  If they are library developers they may know nothing about the client code and DerivedExtended library written by the second development team.  So they make the simple change below:

namespace Core
{
    public class MyCoreClass
    {
        public int CoreValue { get; set; }
 
        public void SetCoreValue()
        {
            myCoreClass.CoreValue = 100;
        }
    }
}

Now if we run our client code we see that the behaviour has been changed: it prints out 100.  However nothing has ostensibly been broken: our DerivedExtended developers could easily rebuild against the new Core library, not spot anything had changed, and ship the code with changed behaviour.  Of course in my simple example it doesn’t look like the effects of this are likely to be catastrophic.  However because of the extension method the DerivedExtended developers now need to be much more careful when the implementation of the Core library changes.

Extension Methods or Inheritance?

Of course, in object-oriented languages we already have a means of extending a class where we don’t necessarily have access to or want to change the original source code: it’s called inheritance.

In C# and other object-oriented languages there is extensive support for allowing a base class writer to control how their class will be extended by inheritance, such as declaring methods as virtual, declaring member variables as protected and so on.  A number of our core design patterns are based around designing classes that can be extended in this way (e.g. Template Method).

Why This Isn’t a Problem with Inheritance

Now consider the same extension as above being made with inheritance.  Firstly we revert our Core class to simply have the CoreValue property:

namespace Core
{
    public class MyCoreClass
    {
        public int CoreValue { get; set; }
    }
}

Then we construct a Derived class that contains a SetCoreValue method that again sets the value to 1.  Thus we extend our code in a new library in the traditional way:

namespace DerivedExtended
{
    public class Derived : Core.MyCoreClass
    {
        public void SetCoreValue()
        {
            base.CoreValue = 1;
        }
    }
}

We can now change our client code to use this extension:

    class Program
    {
        static void Main(string[] args)
        {
            // Now consider case where we extend by inheritance
 
            // Instantiate the Derived class
            Derived derived = new Derived();
 
            // Call the derived method
            derived.SetCoreValue();
 
            // Get property value from derived class and display it
            Console.WriteLine(derived.CoreValue);
 
            Console.ReadLine();
        }
    }

}

And clearly here the code will print out ‘1’ again.

Now, as before, assume our Core library developers add a SetCoreValue method to the Core class, unaware that there already is one in the Derived class:

    public class MyCoreClass
    {
        public int CoreValue { get; set; }
 
        public void SetCoreValue()
        {
            CoreValue = 100;
        }
    }

This doesn’t change the behaviour of the existing client code, which still prints out ‘1’.  However, we get a compiler warning:

‘DerivedExtended.Derived.SetCoreValue()’ hides inherited member ‘Core.MyCoreClass.SetCoreValue()’. Use the new keyword if hiding was intended.

So not only has the code not been broken, but our DerivedExtended developers will get a warning that there is a problem when they come to recompile their code against the new library.

Note also that any code the Core developers write calling SetCoreValue on the Core class will correctly call the Core class version (they don’t know about the Derived class version so can’t want to call it).

This behaviour is deliberate: by default a method in a derived class hides rather than overrides a method with the same signature in a base class if there has been no explicit use of the ‘new’ or ‘virtual/overrides’ keywords.  This is precisely because of the circumstances with regard to extension described here.

Summary

So in summary, in the circumstances described where a development team is extending classes in a library it seems better to do this by inheritance than by extension methods.  Obviously it isn’t always possible to extend a class by inheritance and we may need to use other techniques, but in general extension methods seem fragile to me.

To an extent the same argument applies to any class in our code, whether in a library or not.  Suppose we use extension methods and then later on we alter the implementation of the class we are extending.  We can break our extension methods without necessarily noticing we have done so.  Of course this is true of any code that uses the public interface of our class if its behaviour changes, so is less valid as an argument against extension methods.

MSDN

Microsoft itself agrees with the central argument in this article.  In the page on extension methods in the C# programming guide it says:

General Guidelines

In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance (C# Programming Guide).

When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.

Conclusion

Extension methods can be fragile.  My recommendation is that you don’t write your own extension methods, for the reasons explained above.

June 6, 2009

Running Visual Studio as an Administrator under Windows Vista

Filed under: .net, Visual Studio — Tags: , , , , , — richnewman @ 11:36 pm

Introduction

This article discusses why we should run Visual Studio as an administrator, and examines the easiest way to do that under Windows Vista.

Visual Studio and Administrator Rights

As .Net developers we need to be able to run Visual Studio as a Windows administrator.

Visual Studio 2005 actually warns you at start up if you are not running it as an administrator under Vista, and Microsoft recommends that you always run it with administrator privileges.  In fact MSDN gives a list of scenarios where Visual Studio 2005 will have ‘issues’ if it is not running with these privileges:

http://msdn.microsoft.com/en-us/vstudio/aa972193.aspx

For other versions of Visual Studio and operating systems there are fewer issues about not running Visual Studio as an administrator.  However there are a number of scenarios where you need administrative privileges.  These include needing to install or reinstall anything, or to do any kind of Office add-in work, or to use ActiveX controls, or even just to register a library for COM Interop.

Running Visual Studio as an Administrator

Under earlier versions of Windows developers usually just made themselves local administrators on their development computers to ensure Visual Studio had sufficient privileges.   Under Vista however, this is not enough (it is still necessary to be an administrator, but not sufficient).

This is because if you run an application under Vista by default it does not have administrative privileges unless specifically given them.  This is true even if the user running the application has administrative privileges.

Granting Visual Studio Administrative Privileges

There are (at least) three ways of starting Visual Studio with administrative privileges in Vista.

Note that for all three you need access to an administrator account.  It’s easiest if you are logged in as an administrator, in which case you will simply get a User Account Control warning saying ‘A program needs your permission to continue’ (and you can just click ‘OK’).  If you are not logged in as an administrator the User Account Control will ask you for an administrator’s ID and password before it will launch the program.

The three ways of running Visual Studio with administrative privileges are:

  1. Right-click on the shortcut to Visual Studio and select ‘Run as administrator’ from the context menu.
  2. Type ‘devenv’ into the Start Search box (at the bottom of the Vista Start menu: just hit the Windows key and you are in it).  Then hit Control-Shift-Enter, rather than just Enter.  Control-Shift-Enter tells Windows to start the program with administrative privileges.  This one is for those of you who don’t like reaching for a mouse.
  3. Right-click a shortcut to Visual Studio, select the Compatibility tab, and check the ‘Run this program as an administrator’ checkbox at the bottom.

Always Running Visual Studio as an Administrator

The last of the items above (item 3) is the one to use if you always want to run Visual Studio as an administrator.  Once the checkbox is checked in future you will be able to click on any shortcut to Visual Studio and it will run with elevated privileges.

Note that setting the ‘Run this program as an administrator’ property on a shortcut actually sets it on the underlying executable itself (in this case devenv.exe).  It isn’t possible as far as I can see to have one shortcut that will run the program as an administrator, and another one that will run it with normal privileges.

User Account Control

If you always run Visual Studio as an administrator you are going to get the User Access Control warning every time you start it, even if you are logged in as an administrator to Windows.  Obviously you can just click ‘OK’ to dismiss this warning, but it may tempt you to turn User Access Control off.

Note that this is true only if Vista’s User Account Control (UAC) is turned on.  Many developers turn UAC off, and in this case Vista behaves in the same way as earlier versions of Windows with regard to starting Visual Studio: if you are logged in as an administrator then Visual Studio will by default run with administrative privileges.

The Administrator Account

Vista also has an account called ‘Administrator’ which behaves differently from other administrator accounts.  In fact it behaves like administrator accounts in earlier versions of Windows, in that all programs launched when using it run with administrator privileges by default.  There’s no need to specifically set up the program as described above.

As a developer your really shouldn’t need to use this account: you can develop with administrator privileges using the techniques described in this article.

However you may have occasions when you aren’t sure whether a program is failing because of some coding error or simply because a process is being launched with insufficient privileges.  In these cases it may be useful to use the Administrator account temporarily to simply rule out a problem with privileges.  Note that if you work for a large organization they are almost certainly not going to let you near this account, however: this is really only useful for those developing at home.

Using the Administrator Account

To enable the Administrator account start a command prompt with administrator privileges as described above (type ‘cmd’ in the Start Search box and hit Control-Shift-Enter).  Then enter:

net user Administrator /active:yes

This has a blank password by default.  To set a password use:

net user Administrator {password}

You can now log off and log on as the Administrator.  Once you are done with any testing you should disable this account again as below

net user Administrator /active:no

Note that disabling the account does not clear the password.  However if you forget it you can always set it again as above when you come to use the account again (provided you have access to at least one account with administrator privileges).

Aside: Administrator Account on Windows XP

The Administrator account discussed above is the main default administrator account for a computer.  Previous versions of Windows had this account as well, although other accounts with administrator rights behaved in the same way.

In particular it existed under XP.  Not only that it was enabled by default, and had a blank password.  If you’ve got an XP computer at home try hitting Ctrl-Alt-Del twice on the screen that shows your accounts, and then enter ‘Administrator’ and a blank password.  If that logs you on with admin rights you may want to consider disabling the account as described above.

The Shocking Blue Green Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 80 other followers