簡體   English   中英

如何將多態性與泛型類型一起使用,該泛型類型的類型參數是 C# 中類型參數約束的子類型?

[英]How do I use polymorphism with a generic type who's type argument is a child of the type parameter constraint in c#?

我有一個 genericType,其類型約束是一個基類。 當我嘗試使用類型約束的子類為這種類型分配值時,它不起作用。

我知道這樣做的原因是因為編譯器將它們視為兩種完全不同的類型。

有解決辦法嗎? 我唯一能想到的是創建一個通用類實現的接口,並通過任何方式公開類型。 在下面的示例中,我可以讓 barInstance 成為接口中定義的屬性的實現。 但這會產生一些樣板。 干杯!

public class Bar { }

public class SubclassOfBar : Bar { }

public class GenericClass<T> where T : Bar { 
    public T barInstance;
}

public class Example
{
    public void Test()
    {
        GenericClass<Bar> fooBar = new GenericClass<SubclassOfBar>(); // Does not compile
    }
}

使用界面解決方法:

public class Bar { }

public class SubclassOfBar : Bar { }

public class GenericClass<T> : IHaveBar where T : Bar
{
    public T barInstance;
    public Bar BarInstance => barInstance;
}

public class Example1
{
    public void Test()
    {
        IHaveBar fooBar = new GenericClass<SubclassOfBar>(); // Does Compile
    }

我明白你想做什么,但我不明白為什么。 如果您希望變量 fooBar.BarInstance 僅引用 barInstance 屬性而不是派生實例,則有幾種方法。 我也會扔掉那些明顯的,以防萬一:)

  1. 只需將泛型類型更改為 Bar。

     //Set both to the derived type. GenericClass<Bar> fooBar = new GenericClass<Bar>();
  2. 將兩者都更改為派生類型並執行強制轉換:

     public void Test() { GenericClass<SubclassOfBar> fooBar = new GenericClass<SubclassOfBar>(); var instance = (Bar)fooBar.barInstance; }
  3. 您也可以使用您的解決方案,但不需要界面。

     public class Bar { } public class SubclassOfBar : Bar { } public class GenericClass<T> where T : Bar { private T barInstance; public Bar BarInstance => barInstance; } public class Example { public void Test() { var fooBar = new GenericClass<SubclassOfBar>(); var instance = fooBar.BarInstance; } }
  4. 如果您想從上面的示例中刪除“樣板”代碼,您可以將其全部放在一個抽象類中。 (這假設您將擁有多個這些通用類)。

     public class Bar { } public class SubclassOfBar : Bar { } public abstract class AbstractGenericClass<T> where T : Bar { private T barInstance; public Bar BarInstance => barInstance; } public class GenericClass<T> : AbstractGenericClass<T> where T : Bar { } public class Example { public void Test() { var fooBar = new GenericClass<SubclassOfBar>(); var instance = fooBar.BarInstance; } }

如果我需要澄清任何事情,請告訴我!

快樂編碼!

如果你想在 Test 方法中做一些通用的東西,你也可以在方法中傳遞類型。 代碼會變成這樣。

public void Test<T>() where T : Bar
{
    GenericClass<T> fooBar = new GenericClass<T>();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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