Virtual Static Interface Methods in C# – Implementation

I sketched the question of “virtual static interface methods” in my previous post.

The idea behind my implementation of this feature is to use a class-level attribute to identify the pseudo-static class for a given class:

class FooStatic
{
}

[StaticClass(typeof(FooStatic))]
class Foo
{
}

The pseudo-static class is a normal C# class, therefore we can use available mechanisms such as interfaces and inheritance for it.

Let’s define the attribute:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class StaticClassAttribute : Attribute
{
    Type _type;
    public StaticClassAttribute(Type _type)
    {
        this._type = _type;
    }

    public Type Type { get { return _type; } }
}

Ok, that was easy.

Next, we need a helper class to retrieve the StaticClass attribute from a given type:

public static class StaticHelper
{
    static Type GetStaticType(Type t)
    {
        var attrs = t.GetCustomAttributes(typeof(StaticClassAttribute), true);
        if (attrs.Length == 0) return null;
        return (attrs[0] as StaticClassAttribute).Type;
    }

And some user-friendly helper methods to instantiate an object of the attribute’s class value:

    public static object Get<T>()
    {
        var t = GetStaticType(typeof(T));
        if (t == null) return null;		// or throw NotImplemented
        return t.GetConstructor(Type.EmptyTypes).Invoke(new object[] { });
    }

    public static S Get<T, S>() where S: class
    {
        return Get<T>() as S;
    }

    public static object Get(object o)
    {
        var t = GetStaticType(o.GetType());
        if (t == null) return null;		// or throw NotImplemented
        return t.GetConstructor(Type.EmptyTypes).Invoke(new object[] { });
    }

    public static S Get<S>(object o) where S: class 
    { 
        return Get(o) as S; 
    } 
}

Let’s write our sample static interface and static classes

public interface IStaticSampleClass
{
    void Hello();
}
public class StaticSampleClass : IStaticSampleClass
{
    public void Hello()
    {
        Console.WriteLine("hello from " + this.GetType().Name);
    }
}
public class StaticSampleClass2 : IStaticSampleClass
{
    public void Hello()
    {
        Console.WriteLine("bye from " + this.GetType().Name);
    }
}

and a couple of sample classes

[StaticClass(typeof(StaticSampleClass))]
public class SampleClass
{
}
public class SampleClassEx : SampleClass
{
}

[StaticClass(typeof(StaticSampleClass2))]
public class SampleClass2 : SampleClass
{
}

As you can see, SampleClass and SampleClass2 each declare their respective pseudo-static class, whereas SampleClassEx inherits it from SampleClass.

What does it do?

static void Main(string[] args)
{
    object staticclass;
    staticclass = StaticHelper.Get<SampleClass>();
    Console.WriteLine("static type of SampleClass " + staticclass.GetType().Name);
    staticclass = StaticHelper.Get<SampleClassEx>();
    Console.WriteLine("static type of SampleClassEx " + staticclass.GetType().Name);
    staticclass = StaticHelper.Get<SampleClass2>();
    Console.WriteLine("static type of SampleClass2 " + staticclass.GetType().Name);
    StaticHelper.Get<SampleClass, IStaticSampleClass>().Hello();
    StaticHelper.Get<SampleClass2, IStaticSampleClass>().Hello();

    var o = new SampleClass();
    staticclass = StaticHelper.Get(o);
    Console.WriteLine("static type of SampleClass object " + staticclass.GetType().Name);
    StaticHelper.Get<IStaticSampleClass>(o).Hello();

    Console.ReadLine();
}

The code attempts to retrieve the pseudo-static classes from the classes SampleClass* by using StaticHelper.Get<T>().

The result of Get<T, S> can also be type-cast to an expected interface or class (see lines invoking Hello()).

Finally, the pseudo-static class can also be retrieved via the type of an object parameter to Get(object).

The output of this code is:

static type of SampleClass StaticSampleClass
static type of SampleClassEx StaticSampleClass
static type of SampleClass2 StaticSampleClass2
hello from StaticSampleClass
bye from StaticSampleClass2
static type of SampleClass object StaticSampleClass
hello from StaticSampleClass

One note at the end: While the code I presented works in principal, the implementation is currently not truly static since a StaticClass object is instantiated every time it is referenced. The next post will cover this issue as well.

Advertisements

One Response to Virtual Static Interface Methods in C# – Implementation

  1. […] The implementation of pseudo-static virtual methods I sketched in my previous post has one problem: the implementation is currently not truly static since a StaticClass object is instantiated every time it is referenced […]

Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: