我有一个(非常容易)的问题,似乎我无法找到如何做到这一点。我将不胜感激。
我有两个类是这样的:
public class FileParameters { ... }
public abstract class File {
...
public abstract FileParameters Params { get; }
}
从这两个班级我都有派生的特殊版本:
public class SpecialFileParameters { ... }
public abstract class SpecialFile {
...
private SpecialFileParameters params;
public override FileParameters Params { get { return params; } }
}
当我想使用SpecialFileParameters时,我必须先抛出它们,例如:
((SpecialFileParameters)SpecialFileObject.Parameters).DoSomething();
这是非常讨厌的。我想要的基本上与接口
的语法相同public abstract class SpecialFile {
...
private SpecialFileParameters params;
private override FileParameters File.Params { get { return params; } }
public new SpecialFileParameters Params { get { return params; } }
}
但是像这样我得到一个编译器错误:显式接口声明中的'File'不是接口。还有其他方法可以做到这一点吗?
进一步的信息:
感谢您的帮助(我的耐心,我猜^^),
答案 0 :(得分:2)
在C ++ / CLI中有些不同,例如显式覆盖:
public ref struct BaseClass abstract
{
virtual int Func(int) abstract;
};
public ref struct DerivedClass : BaseClass
{
virtual int BaseFunc(int x) = BaseClass::Func { return x + 2; }
virtual int Func(int y) new { return y / 2; }
};
int main(array<System::String ^> ^args)
{
DerivedClass^ d = gcnew DerivedClass();
BaseClass^ b = d;
System::Console::WriteLine("4 -> Base -> " + b->Func(4));
System::Console::WriteLine("4 -> Derived -> " + d->Func(4));
return 0;
}
Marc已经展示了你需要为C#做些什么:使用额外的继承层。
答案 1 :(得分:1)
不,C#中没有用于标记显式抽象覆盖方法的语法(与具有相同签名的另一个方法不同),并且由于您不能在同一级别中声明两个匹配的签名,因此您无法完成你想要什么。
由于您已排除更改基类,我唯一的建议是添加一个人为的额外级别:
public abstract class File {
public abstract FileParameters Params { get; }
}
public abstract class FileIntermediate : File
{
public override FileParameters Params {get { return ParamsImpl; }}
protected abstract FileParameters ParamsImpl { get; }
}
public class SpecialFile : FileIntermediate
{
public new SpecialFileParameters Params { get { return null; } }// TODO
protected override FileParameters ParamsImpl {get { return Params; }}
}
答案 2 :(得分:0)
您可以使用泛型来解决此问题:
public class FileParameters { }
public class SpecialFileParameters : FileParameters{}
public abstract class File<T>
where T : FileParameters
{
private T _params;
public T Params { get { return _params;} }
}
public class SpecialFileParams : FileParameters<SpecialFileParameters> { }
当您访问Params时,您将获得具体的“特殊”。
答案 3 :(得分:0)
是否需要在两个方法(覆盖和新方法)之间使用相同的方法名称?在这些情况下,我通常使用新名称创建一个新方法,该方法返回更多派生类型,然后让覆盖在其实现中调用此方法:
public override FileParameters Params { get { return SpecialParams; } }
public SpecialFileParameters SpecialParams { get { return params; } }
这样,当你有一个SpecialFile对象时,你不需要强制转换。如果这不起作用,也许你可以解释为什么你需要方法的名称对你的情况是相同的。