標籤:

為什麼 C# 的泛型約束不能約束靜態方法?

比如要求 T 必須實現了 (+) 運算符


不要把C#的template當C++用。C#的template就真的只是template,不像C++是用來做元編程的。


用dynamic啊

class Program
{
static void Main(string[] args)
{
MyClass& c=new MyClass&(1,2);
Console.WriteLine(c.Plus());
}

}

class MyClass&
{
private T a;
private T b;

public MyClass(T a,T b)
{
this.a = a;
this.b = b;
}

public dynamic Plus()
{
dynamic aa = a;
dynamic bb = b;
return aa + bb;
}
}


題目改了,這問題問的。。。「為什麼 C# 的泛型約束不能約束靜態方法」,結果是說為什麼不能約束運算符。

好吧,確實不能,重載的運算符在編譯完事之後就是個普通方法了,對CLR來說,它看不到這個運算符。

更進一步來說,不管是不是靜態,你無法要求泛型約束來限制T存在某些約束裡面指定的方法(無參構造函數是個特例),有哪些參數之類的。

============================================================

沒聽說過靜態泛型方法沒法寫泛型約束的,說出你的需求,看看怎麼沒法約束了。


因為只有實例方法才存在於虛方法表裡啊

.NET泛型操作引用類型的代碼是不變的,都是拿到指針-&>尋找約束的介面-&>查找虛方法表獲得目標方法;而泛型在創建完成後就不和類型對象打交道了,因此無法調用靜態方法。

如果非要這麼做的話,那麼必須給泛型對象一個隱藏的成員,泛型方法一個隱藏的參數,來標識類型實參

(我都跟你解釋過了你還來提問幹什麼)


C#目前就是不支持這種。。。

不過可以在Constructor裡面用反射判斷,沒有指定的方法就拋個異常之類的。

class Generic&
{
static Generic()
{

if (null ==
typeof(T).GetMethod("op_Addition",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, ...
))
{
throw new NotSupportedException();
}
}
...
}

然後要用到的時候再Invoke。


public static void Test&() where T : class
{

}

能啊


推薦閱讀:

如何評價 Unity 2018?
如何解決.NET程序容易被反編譯的問題?
剖析並利用Visual Studio Code在Mac上編譯、調試c#程序
跟Unity學代碼優化

TAG:NET | C# |