為什麼 C# 的泛型約束不能約束靜態方法?
比如要求 T 必須實現了 (+) 運算符
不要把C#的template當C++用。C#的template就真的只是template,不像C++是用來做元編程的。
用dynamic啊
class Program
{
static void Main(string[] args)
{
MyClass&
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&
{
}
能啊
推薦閱讀:
※如何評價 Unity 2018?
※如何解決.NET程序容易被反編譯的問題?
※剖析並利用Visual Studio Code在Mac上編譯、調試c#程序
※跟Unity學代碼優化