Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using static methods of a constrained generic type C#

I have a generic class:

public class Foo<T> where T: Interface
{

}

the interface that T is being forced to implement has 2 static methods defined inside of it.

in the constructor I want to be able to basically do the following:

public Foo()
{
   value1 = T.staticmethod1();
   value2 = T.staticmethod2();
}

This cannot be accomplished with the psuedocode I have posted above. Is it not possible to call these static methods in this way?

like image 973
pquest Avatar asked Aug 08 '11 18:08

pquest


2 Answers

You may be able to use extension methods. This technique has been named pseudo-mixins. Although the extension methods are actually static they "pretend" to be instance methods, so you still need a concrete instance of T.

Also, this is kind of cheating, if you want your interface to preserve its role as a self-documenting "contract" that specifies what methods your T class should have. However they are type-safe (your Foo class will not compile, if you don't bring the IBarExtensions in scope)

//our interface
public interface IBar {}

// the two static methods are define as extension methods
public static class IBarExtensions {
    public static string someMethod1(this IBar self) {
        return "my initialization 1";
    }
    public static string someMethod2(this IBar self) {
        return "my initialization 2";
    }
}

public class Foo<T> where T : IBar, new()
{
    public string value1 {get; private set;}
    public string value2 {get; private set;}

    public Foo() {
        T t = new T(); // we can do this because of the "new()" constraint
                           // in the class definition
                           // Alternatively we could pass an instance of T in
                           // the constructor 
                           // public Foo(T t)
        value1 = t.someMethod1();
        value2 = t.someMethod2();       
    }
}

testing

public class TestBar : IBar {}
void Main()
{
    var c = new TestBar();

    var t = new Foo<TestBar>();
    Console.WriteLine(t.value1);
}
like image 184
Paolo Falabella Avatar answered Sep 20 '22 00:09

Paolo Falabella


No, it is not possible. Not even with dynamic. There are generic constraints (such as interfaces), but that applies to instance members only. You could consider passing those methods in (parameters) as Func<T>/Action<T> delegates?

Beyond that, your only (and undesirable) option is reflection. Or perhaps better: rethink our approach here.

like image 37
Marc Gravell Avatar answered Sep 23 '22 00:09

Marc Gravell