问题描述
我想用派生类类型覆盖虚方法。目前最好的方法是什么?到目前为止,我发现了两种方法:
I want to override a virtual method with a derived class type. What's the current best way to do this? So far I've found two approaches:
- 使用
abstract
base <$每个派生类型的c $ c> class ;使用protected
方法桥接。 - 使用
protected
实现public
accessor。
- Use an
abstract
baseclass
for each derived type; bridge withprotected
methods. - Use a
protected
implementation with apublic
accessor.
基本情况(未实施解决方案,克隆
始终返回基本类型 A1
):
Base case (no solution implemented, Clone
always returns base type A1
):
public class A1
{
public int X1 { get; set; }
public A1(int x1) { this.X1 = x1; }
public virtual A1 Clone() { return new A1(X1); }
}
public class A2 : A1
{
public int X2 { get; set; }
public A2(int x1, int x2) : base(x1) { this.X2 = x2; }
public override A1 Clone() { return new A2(X1, X2); } //can't explicitly return A2
}
public class A3 : A2
{
public int X3 { get; set; }
public A3(int x1, int x2, int x3) : base(x1, x2) { this.X3 = x3; }
public override A1 Clone() { return new A3(X1, X2, X3); } //can't explicitly return A3
}
解决方案#1(使用 abstract
每个派生类型的基类, protected
bridge):
Solution #1 (using abstract
base classes for each derived type with protected
bridges):
public class B1
{
public int X1 { get; set; }
public B1(int x1) { this.X1 = x1; }
public virtual B1 Clone() { return new B1(X1); }
}
public abstract class B2_Base : B1
{
public B2_Base(int x1) : base(x1) { }
public sealed override B1 Clone() { return this.CloneAsB1(); }
protected abstract B1 CloneAsB1();
}
public class B2 : B2_Base
{
public int X2 { get; set; }
public B2(int x1, int x2) : base(x1) { this.X2 = x2; }
protected sealed override B1 CloneAsB1() { return this.Clone(); }
public new virtual B2 Clone() { return new B2(X1, X2); } //CAN explicitly return B2
}
public abstract class B3_Base : B2
{
public B3_Base(int x1, int x2) : base(x1, x2) { }
public sealed override B2 Clone() { return this.CloneAsB2(); }
protected abstract B2 CloneAsB2();
}
public class B3 : B3_Base
{
public int X3 { get; set; }
public B3(int x1, int x2, int x3) : base(x1, x2) { this.X3 = x3; }
protected sealed override B2 CloneAsB2() { return this.Clone(); }
public new virtual B3 Clone() { return new B3(X1, X2, X3); } //CAN explicitly return B3
}
解决方案#2(使用 protected
使用 public
accessors实现:
Solution #2 (using protected
implementation with public
accessors):
public class C1
{
public int X1 { get; set; }
public C1(int x1) { this.X1 = x1; }
public C1 Clone() { return this.CloneImplementation(); }
protected virtual C1 CloneImplementation() { return new C1(X1); }
}
public class C2 : C1
{
public int X2 { get; set; }
public C2(int x1, int x2) : base(x1) { this.X2 = x2; }
public new C2 Clone() { return this.CloneImplementation() as C2; } //trusts CloneImplementation to return a C2
protected override C1 CloneImplementation() { return new C2(X1, X2); }
}
public class C3 : C2
{
public int X3 { get; set; }
public C3(int x1, int x2, int x3) : base(x1, x2) { this.X3 = x3; }
public new C3 Clone() { return this.CloneImplementation() as C3; } //trusts CloneImplementation to return a C3
protected override C1 CloneImplementation() { return new C3(X1, X2, X3); }
}
据我所知,解决方案#1是最严格的方法,但每个派生的类 abstract
base class
>想要替换基础类
的返回类型。
So far as I can tell, Solution #1 is the most rigorous approach, but it requires an abstract
base class
for each derived class
which wants to replace the base class
's return type.
解决方案#2更简单易懂,但它在内部类型安全方面有一个小小的突破。具体来说,每个派生类型的 public
访问器都信任其 protected
方法将返回正确的类型。所以可以有一个内部类型断开,例如:
Solution #2's simpler and easier to understand, but it has a small break in internal type safety. Specifically, each derived type's public
accessor trusts that its protected
method will return the correct type. So it's possible to have an internal type disconnect, e.g.:
public class C2 : C1
{
public int X2 { get; set; }
public C2(int x1, int x2) : base(x1) { this.X2 = x2; }
public new C2 Clone() { return this.CloneImplementation() as C2; } //trusts CloneImplementation to return a C2
protected override C1 CloneImplementation() { return new C1(X1); }
}
是否有一个正确的(普遍接受的)最佳实践来覆盖派生方法类型?
Is there a correct (generally accepted) best practice for overriding methods with derived types?
推荐答案
您可以使基类通用:
public abstract class Base<TDerived> where TDerived : Base {
public abstract TDerived Clone();
}
public class Derived1 : Base<Derived1> {
public override Derived1 Clone() { ... }
}
public class Derived2 : Base<Derived2> {
public override Derived2 Clone() { ... }
}
然而,这让我想知道有一个共同的基类是多么有用。也许Derived1和Derived2的Clone实现不需要是通用接口的一部分。
However this makes me wonder how useful having a common base class is. Perhaps the Clone implementations of Derived1 and Derived2 don't need to be part of a common interface.
这篇关于如何在C#中使用派生返回类型覆盖方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!