我正在考虑使用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映射到数据库。
有没有人做过这样的事情?值得推荐吗?有没有其他方法可以解决同样的问题?
编辑:由于讨论了关于强制转换和属性的实现,我稍微改变了代码。这实际上不是问题。我只是尝试编写尽可能少的代码来做一个简短的例子。
答案 0 :(得分:2)
我认为你正在向后做...堕落者会失败,你应该用向上的方式设计它。 IEnumerable
的实施是这种模式最常见的例子。
最派生的类型需要负责创建派生最多的结果,然后可以重写基类型中的虚方法,以通过upcast返回最大的派生结果(可能是隐式的)。
答案 1 :(得分:2)
我会不这样做。
这只是为了保存打字而且会降低您的效果,因为B3.MyA
基本上会return (A3)(A2)this.MyA;
。只有在必要时才能直接b3.MyA as A3
进行太多不必要的演员表。
此外,如果您忘记MyA
B3
A3
中A1
类型的对象,您的演员表将失败,因为它将是A2
类型的对象或Technically it would work, but it just gets very complicated.
或其他什么。你可以很容易地在腿上射击。
编辑:我所写的内容是:不这是一种类型安全的方法,永远不会。您可以最大限度地降低这样做的风险(例如您编辑的代码显示),但仍有可能。恕我直言,这种结构的好处并不能证明这种危险是正确的。
Edit2 :请注意通用方法中的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();
语句:
{{1}}