Using static methods of limited generic type C #

I have a general class:

public class Foo<T> where T: Interface { } 

the interface that T enforces has 2 static methods defined inside 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 achieved using psuedocode, which I posted above. Is it impossible to invoke these static methods this way?

+6
source share
5 answers

You may be able to use extension methods. This method has been called pseudomyxins . Although extension methods are actually static, they pretend to be instances, so you still need a specific instance of T.

It’s also a kind of trick if you want your interface to retain its role as a self-documenting “contract” that determines which methods your T class should have. However, they are type safe (your Foo class will not compile unless you bring IBarExtensions to 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); } 
+9
source

No, It is Immpossible. Even with dynamic . There are general restrictions (such as interfaces), but this only applies to instance members. Could you consider passing these methods in (parameters) as Func<T> / Action<T> delegates?

In addition, your only (and undesirable) option is reflection. Or maybe better: rethink our approach here.

+4
source

C # does not allow calling static methods defined in interfaces. It produces an ill-named error message:

CS0017 also occurs if you use a library written in a language that allows static members in interfaces, and you are trying to access a static member from C #.

If C # allows this, you should use the interface name, not the name of the generic parameter, to call them:

 // doesn't work: public Foo() { value1 = Interface.staticmethod1(); value2 = Interface.staticmethod2(); } 

So, you have several options:

  • Use a language that allows you to call these members (I think it is VB.NET and C ++ / CLI). You can write a small adaptation that you can use with C #;
  • Ask the people who provided you with this interface (maybe even you) to avoid using static elements in the interfaces. They can be moved to separate static classes. A class can even be embedded in an interface (if the language allows it), and it will work with C #.
+1
source

It is not possible to use static members of restricted parameters of a type type, since the existence of a static member in a particular type does not indicate whether the derived type will have a compatible element with this name. Suppose that type “Foo” has a static function Wowzo () that returns Int32, type DerivedFoo1 has another static function Wowzo () that also returns Int32, type DerivedFoo2 (which comes from Foo), has a static member Wowzo () that returns String, and the type DerivedFoo3 has a nested Wowzo class. If T is a type parameter restricted to being a descendant of Foo, what is T.Wowzo?

+1
source

You can also use the non-stationary method as a wrapper calling your static method. The non-stationary method may be part of your interface.

0
source

Source: https://habr.com/ru/post/894571/


All Articles