C# 从泛型中继承 class 作为类型
C# inherited class from generic as a type
我对泛型有疑问。我有那些 classes :
abstract class BaseTestClass<T> : where T : class, new()
{
//base test class implementation
public abstract void Run(BaseDataClass<T> data);
}
class BaseDataClass<T> : where T : class, new()
{
//base data class implementation
}
class DataA : BaseDataClass<SettingsA>
{
//some stuff
}
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
}
//Doesn't Work!
public override void Run(DataA data)
{
}
}
我的问题是为什么我不能在抽象方法中使用继承的class?
[编辑]
编译时的错误是:
TestA does not implement inherited abstract member Run(BaseDataClass)
它不起作用,因为您不能用两种方法覆盖一种方法。取消对 TestA 中的一种方法的覆盖,它将全部起作用。无论如何,在单个 class.
中两次覆盖单个方法是没有意义的
可以,但是 BaseTestClass<SettingsA>
基础 class 根本没有覆盖签名 Run(DataA)
的方法,只有签名 Run(BaseDataClass<DataA>)
之一。
泛型继承也就是泛型T类型相同
你的第二个方法没有编译,因为没有方法可以被它覆盖,删除 override
修饰符将使你的代码编译。
如果你想有一个方法运行只在参数为DataA类型时,但仍然执行接口方法实现,你可以这样做:
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
}
public void Run(DataA data)
{
//dp some stuff
Run((BaseDataClass<SettingsA>)data);
}
}
但请注意,这不是防弹的,您可能会错过盒装电话,更好的方法是这样做:
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
var myDataA = data as DataA;
if (myDataA != null)
{
//your parameter is a DataA;
}
}
}
您可以使用额外的泛型参数、类型安全且不强制转换来实现此功能:
internal abstract class BaseTestClass<T, Y>
where T : class, new()
where Y : BaseDataClass<T>
{
private T m_data;
//base test class implementation
public abstract void Run(Y data);
}
public class BaseDataClass<T> where T : class, new()
{
}
internal class TestA : BaseTestClass<SettingsA, DataA>
{
public override void Run(DataA data)
{
throw new NotImplementedException();
}
}
class DataA : BaseDataClass<SettingsA>
{
}
class SettingsA
{
}
这是类型安全的,因为约束是
where Y : BaseDataClass<T>
如果你不需要直接在你的基础class中使用T,你可以只使用一个通用参数并删除T
我对泛型有疑问。我有那些 classes :
abstract class BaseTestClass<T> : where T : class, new()
{
//base test class implementation
public abstract void Run(BaseDataClass<T> data);
}
class BaseDataClass<T> : where T : class, new()
{
//base data class implementation
}
class DataA : BaseDataClass<SettingsA>
{
//some stuff
}
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
}
//Doesn't Work!
public override void Run(DataA data)
{
}
}
我的问题是为什么我不能在抽象方法中使用继承的class?
[编辑] 编译时的错误是:
TestA does not implement inherited abstract member Run(BaseDataClass)
它不起作用,因为您不能用两种方法覆盖一种方法。取消对 TestA 中的一种方法的覆盖,它将全部起作用。无论如何,在单个 class.
中两次覆盖单个方法是没有意义的可以,但是 BaseTestClass<SettingsA>
基础 class 根本没有覆盖签名 Run(DataA)
的方法,只有签名 Run(BaseDataClass<DataA>)
之一。
泛型继承也就是泛型T类型相同
你的第二个方法没有编译,因为没有方法可以被它覆盖,删除 override
修饰符将使你的代码编译。
如果你想有一个方法运行只在参数为DataA类型时,但仍然执行接口方法实现,你可以这样做:
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
}
public void Run(DataA data)
{
//dp some stuff
Run((BaseDataClass<SettingsA>)data);
}
}
但请注意,这不是防弹的,您可能会错过盒装电话,更好的方法是这样做:
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
var myDataA = data as DataA;
if (myDataA != null)
{
//your parameter is a DataA;
}
}
}
您可以使用额外的泛型参数、类型安全且不强制转换来实现此功能:
internal abstract class BaseTestClass<T, Y>
where T : class, new()
where Y : BaseDataClass<T>
{
private T m_data;
//base test class implementation
public abstract void Run(Y data);
}
public class BaseDataClass<T> where T : class, new()
{
}
internal class TestA : BaseTestClass<SettingsA, DataA>
{
public override void Run(DataA data)
{
throw new NotImplementedException();
}
}
class DataA : BaseDataClass<SettingsA>
{
}
class SettingsA
{
}
这是类型安全的,因为约束是
where Y : BaseDataClass<T>
如果你不需要直接在你的基础class中使用T,你可以只使用一个通用参数并删除T