3

我正在考虑使用new重新定义子类中的成员以提供更具体的返回类型。问题是:这是个好主意,还是自找麻烦?

要解决的问题是当有几个“镜像”类层次结构时,每个层次结构层的类型都引用另一个层次结构的同一级别。很难解释,所以举个例子:

class A1 {}
class A2 : A1 {}
class A3 : A2 {}

abstract class B1
{
  protected A1 myA;

  A1 MyA { get { return myA; } }
}

abstract class B2 : B1
{
  new A2 MyA { get { return (A2)myA; } }
}

class B3 : B2
{
  new A3 MyA 
  { 
    get { return (A3)myA; } 
    set { myA = value; }
  }
}

有代码只处理抽象的“级别”1(A1/B1等),其他级别也一样。如果每个“级别”都能看到尽可能具体的类型,那就太好了。目前,我在最顶层定义了类型,并在调用代码中一直向下转换。有时我使用另一个名称为某个“级别”添加另一个成员,这会导致更多的冗余成员。我想让它更干净。

(泛型在这里不是一个选项,因为B2不知道就不会有用B3(那里需要额外的接口)。如果有很多类型(例如,还有 C1/2/3、D1/2/3 ...)会有太多通用参数。从技术上讲,它会起作用,但它会变得非常复杂。)

此外,我将序列化其中的一些类 ( DataContractSerializer),并使用 NHibernate 将一些类映射到数据库。

有没有人已经做过这样的事情?值得推荐吗?有没有其他方法可以解决同类问题?

编辑:由于关于演员表和属性实现的讨论,我稍微更改了代码。这实际上不是这里的问题。我只是试着写尽可能少的代码来做一个简短的例子。

4

2 回答 2

2

会这样做。

无论如何,这只是为了节省打字,它会降低你的性能,因为B3.MyA基本上会这样做return (A3)(A2)this.MyA;。太多不必要的演员表,而你b3.MyA as A3只能在必要时直接做。

此外,如果您忘记初始化为 type 的对象MyA,您的演员将失败,因为它将是 type或其他的对象。您可以轻松地射击自己的腿。B3A3A1A2

编辑:我写的重点是:这不是一种类型安全的方式,而且永远不会。您可以将这样做的风险降到最低(例如您编辑的代码显示),但可能性仍然存在。恕我直言,这种结构的好处并不能证明危险是正当的。

Edit2:注意您Technically it would work, but it just gets very complicated.的通用方法。

恕我直言,没那么复杂。为了比较:

public abstract class B1<TA, TC> where TA: A1 where TC: A1
{
    public TA MyA { get; protected set; }
    public TC MyC { get; protected set; }
}

public abstract class B2<TA, TC> : B1<TA, TC> where TA : A2 where TC : A2
{
}

public class B3 : B2<A3, A3>
{
}

更少的代码,更好的安全性,记住using如果你不喜欢太多的输入,你可以随时使用该语句:

using ClassicB2 = MemberHiding.B2<MemberHiding.A3, MemberHiding.A3>;
ClassicB2 b3 = new B3();
于 2010-07-08T09:23:16.493 回答
2

我认为你是在倒退......向下转换会失败,你应该用向上转换来设计它。的实现IEnumerable是这种模式最常见的例子。

派生程度最高的类型需要负责创建派生程度最高的结果,然后可以覆盖基类型中的虚拟方法以通过向上转换(可能是隐式的)返回派生程度最高的结果。

于 2010-07-08T08:53:41.357 回答