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?
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);
}
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.
C# doesn't allow you to call static methods defined in interfaces. It issues a poorly named error message:
CS0017 also occurs if you use a library written in a language that allows static members in interfaces, and you try to access the static member from C#.
If C# would allow it, you'd use the interface name, and not the generic parameter name, to call them:
// doesn't work:
public Foo() {
value1 = Interface.staticmethod1();
value2 = Interface.staticmethod2();
}
So, you have a couple of options:
It is not possible to use static members of constrained generic type parameters, because the existence of a static member in a particular type says nothing about whether a derived type will have a compatible member with that name. Suppose that type "Foo" has a static function Wowzo() that returns an Int32, type DerivedFoo1 has a different static function Wowzo() that also returns an Int32, type DerivedFoo2 (which derives from Foo), has a static member Wowzo() that returns a String, and type DerivedFoo3 has a nested class called Wowzo. If T is a type parameter constrained to be a descendant of Foo, what is T.Wowzo?
You could also have a non static method as a wrapper calling your static method. The non static method can then be part of your interface.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.