[英]Problems with abstract types and interafaces as generic type params with the new() constraint
我需要將泛型類型參數作為接口,但是我想在泛型類(SomeGenericType)中實例化類型,如下所示:
class Program
{
static void Main(string[] args)
{
var val = new SomeGenericType<ISomeInterface>();
Console.ReadKey();
}
}
internal class SomeGenericType<T> where T : new()
{
public SomeGenericType()
{
var test = new T();
}
}
public class SomeClass : ISomeInterface
{
public string TestVal { get; set; }
}
public interface ISomeInterface
{
string TestVal { get; set; }
}
這會拋出以下編譯時錯誤:
“ISomeInterface必須是具有公共無參數構造函數的非抽象類型,以便在泛型類型或方法SomeGenericType中將其用作參數'T'”
我理解為什么會這樣,但是我想知道這個問題是否有任何解決辦法?
謝謝。
不, new()
約束要求可以使用語法創建該類型的實例
new T()
這顯然不適用於抽象類或接口,只是具有公共無參數構造函數的具體類。
您可以通過刪除約束將問題推遲到運行時,並使用:
Activator.CreateInstance<T>()
而是創建對象。 然后,只要運行時使用的實際類型滿足這些約束,您的代碼就會按照您的意願運行。 但是,如果您嘗試使用接口或抽象類,則會遇到運行時錯誤。
在您的特定情況下,此行將引發異常
var val = Activator.CreateInstance<SomeGenericType<ISomeInterface>>();
您已經過了編譯時錯誤,但沒有效果。
一個替代的想法,可能是無關緊要的,但看起來你正在尋找一種方法來要求一個ISomeInterface
,並有一個其默認的實現SomeClass
提供的實例。 這是控制反轉(IOC)容器可以為您處理的事情。 如果您想進一步調查,可以查看Spring.NET,Microsoft Unity,AutoFac,LinFu或許多其他框架之一。
這里的問題是new
約束與具體類型實現有關。 這不能用於簡單的接口或抽象類,因為它們不能直接實例化。 你必須在這里提供一個具體的課程
var val = new SomeGenericType<SomeClass>()
問題是,編譯器無法知道為給定接口實例化哪個類。 正如大衛M指出:
這是控制反轉(IOC)容器可以為您處理的事情
我認為使用框架可能會因為這個簡單的要求而過度殺戮。 你可以做的就是像這樣創建一個自己的Factory
類:
public class Factory
{
Dictionary<Type, Type> typeMapping = new Dictionary<Type, Type>();
public void Register<IType, CType>()
{
typeMapping.Add(typeof(IType),typeof(CType));
}
public IType Create<IType>()
{
Activator.CreateInstance(typeMapping[typeof(IType)]);
}
}
投入一些健全性檢查,這個課程應該可以使用了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.