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