有没有办法覆盖 C# 中的返回类型?如果是如何,如果不是为什么以及推荐的方法是什么?
我的情况是,我有一个带有抽象基类及其后代的接口(interface)。我想这样做(好吧不是真的,但作为一个例子!):
public interface Animal
{
Poo Excrement { get; }
}
public class AnimalBase
{
public virtual Poo Excrement { get { return new Poo(); } }
}
public class Dog
{
// No override, just return normal poo like normal animal
}
public class Cat
{
public override RadioactivePoo Excrement { get { return new RadioActivePoo(); } }
}
RadioactivePoo
当然继承自Poo
。
我想要这样做的原因是那些使用 Cat
对象的人可以使用 Excrement
属性,而不必将 Poo
转换为 RadioactivePoo
而例如 Cat
可能仍然是 Animal
列表的一部分,用户可能不一定知道或关心他们的放射性便便。希望这是有道理的...
据我所知,编译器至少不允许这样做。所以我想这是不可能的。但是你会推荐什么来解决这个问题?
最佳答案
通用基类怎么样?
public class Poo { }
public class RadioactivePoo : Poo { }
public class BaseAnimal<PooType>
where PooType : Poo, new() {
PooType Excrement {
get { return new PooType(); }
}
}
public class Dog : BaseAnimal<Poo> { }
public class Cat : BaseAnimal<RadioactivePoo> { }
编辑:一个新的解决方案,使用扩展方法和标记接口(interface)...
public class Poo { }
public class RadioactivePoo : Poo { }
// just a marker interface, to get the poo type
public interface IPooProvider<PooType> { }
// Extension method to get the correct type of excrement
public static class IPooProviderExtension {
public static PooType StronglyTypedExcrement<PooType>(
this IPooProvider<PooType> iPooProvider)
where PooType : Poo {
BaseAnimal animal = iPooProvider as BaseAnimal;
if (null == animal) {
throw new InvalidArgumentException("iPooProvider must be a BaseAnimal.");
}
return (PooType)animal.Excrement;
}
}
public class BaseAnimal {
public virtual Poo Excrement {
get { return new Poo(); }
}
}
public class Dog : BaseAnimal, IPooProvider<Poo> { }
public class Cat : BaseAnimal, IPooProvider<RadioactivePoo> {
public override Poo Excrement {
get { return new RadioactivePoo(); }
}
}
class Program {
static void Main(string[] args) {
Dog dog = new Dog();
Poo dogPoo = dog.Excrement;
Cat cat = new Cat();
RadioactivePoo catPoo = cat.StronglyTypedExcrement();
}
}
这样 Dog 和 Cat 都继承自 Animal(如评论中所述,我的第一个解决方案没有保留继承)。
有必要使用标记接口(interface)显式标记类,这很痛苦,但也许这可以给您一些想法...
第二次编辑 @Svish:我修改了代码以明确显示扩展方法没有以任何方式强制执行 iPooProvider
继承自 BaseAnimal< 的事实
。 “更强类型”是什么意思?
关于C#:覆盖返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1048884/