簡體   English   中英

抽象類型和交互作用的問題作為泛型類型params與new()約束

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM