簡體   English   中英

如何將子類型傳遞給父 class C# 中的泛型

[英]How to pass child type to generic in parent class C#

我目前正在使用第三方 dll 並且無法選擇關閉它或不使用它。 我有一個看起來像這樣的 class:

public abstract class ParentClass<T> : ApiClass<T> where T : ApiClass<T>
{
    //...stuff
}

如果我想創建一個 Dictionary 或返回 ParentClass 類型,這會導致一些問題,這樣我就不需要事先知道它是哪個子 class。 為了更容易圍繞這個開發,我想做這樣的事情:

//ChildClass should be what is passed to the generic, without directly referencing it
public abstract class ParentClass : ApiClass<InheritedClass>
{
    //...stuff
}

public class ChildClass : ParentClass
{

}

//Now I could define a dictionary like
Dictionary<KeyClass, ParentClass> Map;

像第二個示例一樣定義它可以讓我創建一個字典,因為當我沒有通用值時,我不確定第一個字典是否可以定義? 關於 ApiClass 的更多信息,ApiClass 的定義如下所示:

public abstract class ApiClass<Wrapper> : OtherApiClass where Wrapper : ApiClass<Wrapper>
{
    //...Stuff
}

因此,在這樣的場景中,我將如何定義沒有泛型的 ParentClass,但傳遞給 ApiClass 的類型是 ParentClass 的子 class(ApiClass 明確需要子類型)?

編輯:澄清一點 InheritedClass 的值

Edit2:我不是在尋找替代品,我在問如何。 如果我傳遞除最后一個繼承的 class (我在問題開頭定義的當前 ParentClass )以外的任何東西,Api 將崩潰。 如果語法存在,它看起來像

public abstract class ParentClass : ApiClass<typeof(this)>

我想你正在使用的第三方庫定義ApiClass是這樣的:

public abstract class ApiClass<T> where T : ApiClass<T>

這是一個奇怪重復出現的模板模式的例子。

讓我們把它變成一個具體的例子:

public abstract class ApiClass<T> where T : ApiClass<T>
{
    public abstract T GetNewInstance();
}

如果我有那個代碼,我可以像這樣使用它:

public class MyApiClass : ApiClass<MyApiClass>
{
    public override MyApiClass GetNewInstance()
    {
        return new MyApiClass();
    }
}

這允許MyApiClass有一個方法,定義為父 class 中的抽象方法,它知道當前實例。 Eric Lippert 在這里討論了這個問題

它的缺點是可以被濫用:

public class MyNefariousApiClass : ApiClass<MyApiClass>
{
    public override MyApiClass GetNewInstance()
    {
        throw new NotImplementedException();
    }
}

這是合法的,但 C# 沒有辦法強制您使用 class 本身作為通用參數。 如果我們有class MyNefariousApiClass: ApiClass<this>它會,但我們沒有。

現在,當你說你有一個 class public abstract class ParentClass<T>: ApiClass<T> where T: ApiClass<T>這是你使用第三方庫的代碼。

如果是這樣,那么這不是使用這種模式的正常方式。 如果您要覆蓋 class 它應該如下所示:

public abstract class ParentClass<T> : ApiClass<T> where T : ParentClass<T>

然后我們可以把它帶到最后一點,並像這樣定義ChildClass

public class ChildClass : ParentClass<ChildClass>
{ }

現在,如果您想要一個可以容納任何此類ChildClass的字典,那么您將被卡住,因為父類是通用的。 唯一有點明智的解決方法是使用接口。

public interface IParent
{ }

public abstract class ParentClass<T> : ApiClass<T>, IParent where T : ParentClass<T> 
{ }

然后你可以寫Dictionary<KeyClass, IParent> dictionary = new...

暫無
暫無

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

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