我遇到了泛型问题。我是那些课程:
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)
{
}
}
我的问题是,为什么我不能在抽象方法中使用继承的类?
[编辑] 编译时的错误是:
TestA不实现继承的抽象成员Run(BaseDataClass)
答案 0 :(得分:5)
你可以,但是BaseTestClass<SettingsA>
基类根本没有覆盖签名Run(DataA)
的方法,只有一个签名Run(BaseDataClass<DataA>)
。
通用继承也意味着通用T类型是相同的。
答案 1 :(得分:2)
您可以使用额外的通用参数Type-Safe和不使用强制转换来实现此目的:
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>
如果您不直接在基类中使用T,则只能使用一个通用参数并删除T
答案 2 :(得分:1)
它不起作用,因为你不能用两种方法覆盖一个方法。从TestA中的一个方法中删除它,它将全部起作用。无论如何,在单个班级内两次覆盖单个方法毫无意义。
答案 3 :(得分:1)
你的第二个方法没有编译,因为没有方法可以被它覆盖,删除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;
}
}
}