如何在C#中的子类的重写方法中返回子类型?
我有一个子类,它有一个过度使用的方法,我知道它总是返回基类中声明的返回类型的特定子类型。如果我这样写代码,它将无法编译。因为这可能没有意义,让我举一个代码示例:如何在C#中的子类的重写方法中返回子类型?,c#,inheritance,C#,Inheritance,我有一个子类,它有一个过度使用的方法,我知道它总是返回基类中声明的返回类型的特定子类型。如果我这样写代码,它将无法编译。因为这可能没有意义,让我举一个代码示例: class BaseReturnType { } class DerivedReturnType : BaseReturnType { } abstract class BaseClass { public abstract BaseReturnType PolymorphicMethod(); } class Derive
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass {
public abstract BaseReturnType PolymorphicMethod();
}
class DerivedClass : BaseClass {
// Compile Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override DerivedReturnType PolymorphicMethod() {
return new DerivedReturnType();
}
}
有没有办法用C#来实现这一点?如果不是,实现类似目标的最佳方式是什么?为什么不允许呢?它似乎不允许任何逻辑不一致,因为从过度使用的方法返回的任何对象仍然
是BaseReturnType
。也许有些事情我没有考虑过。或者原因可能是技术或历史原因。不幸的是,C#中不支持协变返回类型来进行方法重写。(与逆变参数类型相同。)
如果您正在实现一个接口,您可以使用“弱”版本显式地实现它,还可以提供一个具有更强契约的公共版本。对于父类的简单重写,恐怕您没有这样的特权:(
(编辑:Marc有一个-虽然它很难看,而且方法隐藏通常对可读性是一件坏事。没有冒犯的意思,Marc;)
我相信这实际上是一个CLR限制,不仅仅是语言限制——但我很可能是错的
(历史上,Java(该语言)在1.5之前有相同的限制,但它与泛型同时获得协变。)不幸的是,C中不支持协变返回类型用于方法重写(与逆变参数类型相同) 如果您正在实现一个接口,那么您可以使用“弱”版本显式地实现它,还可以提供具有更强契约的公共版本 (编辑:Marc有一个-虽然它很难看,而且方法隐藏通常对可读性是一件坏事。没有冒犯的意思,Marc;) 我相信这实际上是一个CLR限制,不仅仅是语言限制——但我很可能是错的
(历史上,Java(语言)在1.5之前有相同的限制,但它与泛型同时获得协方差。)在我看来,您需要返回接口,而不是基类。在我看来,您需要返回接口,而不是基类
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass {
public abstract BaseReturnType PolymorphicMethod();
}
class DerivedClass : BaseClass {
// Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override BaseReturnType PolymorphicMethod() {
return new DerivedReturnType();
}
}
这应该行得通
这应该可以如果引入一个额外的方法来覆盖,您可以这样做(因为您不能
覆盖
和新建
相同类型中具有相同名称的方法):
现在,您在每个级别都有了一个具有正确类型的
PolymorphicMethod
方法。如果引入一个额外的方法来覆盖,您可以这样做(因为您不能覆盖和新的相同类型中具有相同名称的方法):
现在,您在每个级别都有了一个具有正确类型的PolymorphicMethod
方法。如果您不介意的话,您可以将类设置为泛型:
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass<T> where T : BaseReturnType
{
public abstract T PolymorphicMethod();
}
class DerivedClass : BaseClass<DerivedReturnType>
{
// Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override DerivedReturnType PolymorphicMethod()
{
return new DerivedReturnType();
}
}
class BaseReturnType{}
类DerivedReturnType:BaseReturnType{}
抽象类基类,其中T:BaseReturnType
{
公共摘要T多态方法();
}
类派生类:基类
{
//错误:返回类型必须为“BaseReturnType”才能匹配
//重写的成员“BaseClass.PolymorphicMethod()”
公共重写DerivedReturnType多态方法()
{
返回新的DerivedReturnType();
}
}
如果您不介意的话,可以将类设置为泛型:
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass<T> where T : BaseReturnType
{
public abstract T PolymorphicMethod();
}
class DerivedClass : BaseClass<DerivedReturnType>
{
// Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override DerivedReturnType PolymorphicMethod()
{
return new DerivedReturnType();
}
}
class BaseReturnType{}
类DerivedReturnType:BaseReturnType{}
抽象类基类,其中T:BaseReturnType
{
公共摘要T多态方法();
}
类派生类:基类
{
//错误:返回类型必须为“BaseReturnType”才能匹配
//重写的成员“BaseClass.PolymorphicMethod()”
公共重写DerivedReturnType多态方法()
{
返回新的DerivedReturnType();
}
}
将派生类上的方法签名更改为:
public override BaseReturnType PolymorphicMethod()
{
return new DerivedReturnType();
}
C#不支持变量返回类型。您可以查看这篇文章,了解使用泛型实现这一点的方法
以下是在模型中使用泛型的示例:
public class BaseReturnType
{
}
public class DerivedReturnType : BaseReturnType
{
}
public abstract class BaseClass<T> where T : BaseReturnType
{
public abstract T PolymorphicMethod();
}
public class DerviedClass : BaseClass<DerivedReturnType>
{
public override DerivedReturnType PolymorphicMethod()
{
throw new NotImplementedException();
}
}
公共类BaseReturnType
{
}
公共类DerivedReturnType:BaseReturnType
{
}
公共抽象类基类,其中T:BaseReturnType
{
公共摘要T多态方法();
}
公共类DerviedClass:基类
{
公共重写DerivedReturnType多态方法()
{
抛出新的NotImplementedException();
}
}
将派生类上的方法签名更改为:
public override BaseReturnType PolymorphicMethod()
{
return new DerivedReturnType();
}
C#不支持变量返回类型。您可以查看这篇文章,了解使用泛型实现这一点的方法
以下是在模型中使用泛型的示例:
public class BaseReturnType
{
}
public class DerivedReturnType : BaseReturnType
{
}
public abstract class BaseClass<T> where T : BaseReturnType
{
public abstract T PolymorphicMethod();
}
public class DerviedClass : BaseClass<DerivedReturnType>
{
public override DerivedReturnType PolymorphicMethod()
{
throw new NotImplementedException();
}
}
公共类BaseReturnType
{
}
公共类DerivedReturnType:BaseReturnType
{
}
公共抽象类基类,其中T:BaseReturnType
{
公共摘要T多态方法();
}
公共类DerviedClass:基类
{
公共重写DerivedReturnType多态方法()
{
抛出新的NotImplementedException();
}
}
泛型不一定是要走的路。特别是,(派生的)类型不被认为是(基的)类型
首先,向派生类添加一个新方法,该方法将返回正确类型的值。其次,将重写方法标记为不可重写,并将其委托给新方法
就这样。您已经解决了问题。子类将无法重新扩展该类型,因为它们必须重写您的新方法
如果代码不太正确,我深表歉意;我已经习惯了VB.net
abstract class C1 {
public abstract IEnumerable<Byte> F1();
}
class C2 : C1 {
public sealed override IEnumerable<Byte> F1() {
Return F2();
}
public overridable IList<Byte> F2() {
Return {1, 2, 3, 4};
}
}
抽象类C1{
公共抽象IEnumerable F1();
}
C2类:C1类{
公共密封覆盖IEnumerable F1(){
返回F2();
}
P