C# 抽象方法是否有明确的接口声明?
我有一个(相当简单的)问题,似乎我不知道怎么做。我希望能得到一些帮助 我有两门课是这样的:C# 抽象方法是否有明确的接口声明?,c#,.net,c++-cli,C#,.net,C++ Cli,我有一个(相当简单的)问题,似乎我不知道怎么做。我希望能得到一些帮助 我有两门课是这样的: public class FileParameters { ... } public abstract class File { ... public abstract FileParameters Params { get; } } 从这两个类中,我都有一个派生的特殊版本: public class SpecialFileParameters { ... } public abst
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”不是接口。还有别的办法吗
一些进一步资料:
- 我不能更改基类,只能更改我的特殊类
- 我实际上需要两个特殊的派生类,一个是用C#编写的,另一个是用C++/CLI编写的。如果使“工作”的技巧在C和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; }}
}
您可以使用泛型来解决此问题:
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> { }
公共类文件参数{}
公共类SpecialFileParameters:FileParameters{}
公共抽象类文件
其中T:FileParameters
{
私人T_参数;
公共T参数{get{return_Params;}}
}
公共类SpecialFileParams:FileParameters{}
当您访问参数时,您将得到具体的“特殊”值。两个方法(覆盖和新方法)之间是否需要具有相同的方法名?在这些情况下,我通常使用返回更派生类型的新名称创建一个新方法,然后让重写在其实现中调用此方法:
public override FileParameters Params { get { return SpecialParams; } }
public SpecialFileParameters SpecialParams { get { return params; } }
这样,当您有一个特殊文件对象时,您就不需要强制转换。如果这不起作用,也许您可以进一步解释为什么需要方法的名称与您的情况相同。在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;
}
public ref struct基类摘要
{
虚int函数(int)抽象;
};
公共引用结构DerivedClass:基类
{
虚int BaseFunc(int x)=基类::Func{return x+2;}
虚int Func(int y)new{返回y/2;}
};
int main(数组^args)
{
DerivedClass ^d=gcnew DerivedClass();
基类^b=d;
系统::控制台::写线(“4->Base->”+b->Func(4));
系统::控制台::写线(“4->派生->”+d->Func(4));
返回0;
}
Marc已经展示了你需要为C#做什么:使用额外的继承层。@bitxwise我错过了这一部分。。在这种情况下,没有办法避免演员阵容。您可以使用具有不同名称的单独getter来获得类型安全版本,但如果您仅限于抽象基中定义的getter,那么这就是您必须遵守的契约……在我看来,显式重写与问题(即,问题要求的内容错误)并不相关。我认为OP真正想要的是协变返回类型,这在C++/CLI(参见C2392)中不受支持,据我所知,在C#中对于抽象类(与接口相反)不受支持。@ildjarn:显式重写对于缺少协变返回来说不是一个完美的解决办法。另外,该错误消息的描述并不准确。错误消息本身是正确的:托管类型中不允许协变返回。但是描述中说,在使用
/clr
编译时不允许使用协变返回,而实际行为是,无论设置了/clr
,本机类型都允许协变返回。抱歉,我已经厌倦了,并且误读了代码试图执行的操作。编辑,这样我可以删除否决票。