【发布时间】:2012-01-12 00:59:07
【问题描述】:
我有以下课程:
class Alpha
{
}
class Beta : Alpha
{
}
class Gamma : Beta
{
}
class Epsilon : Beta
{
}
我有几个方法可以将它们作为参数:
void Receiver(Gamma gamma);
void Receiver(Epsilon epsilon);
void Receiver(Beta beta);
void Receiver(Alpha alpha);
我在这里需要一些不寻常的东西。
我希望能够将 Alpha 对象传递给所有方法,但我不希望像 void Receiver(Beta beta); 这样的方法能够接收从 Beta 继承的类型的对象(也就是说,我想在最坏的情况下引发Exception 如果传递了 Gamma 或 Epsilon 对象。
我怎样才能以足够通用的方式最好地实现这一点?
我在考虑第一部分,我应该有一个允许向上转换的方法,例如
class Alpha
{
public T Upcast<T>() where T : Alpha
{
// somehow return a T
}
}
这里的问题是我希望它能够在所有级别上工作,例如我也希望能够“向上转换”Beta。
第二部分应该更简单,因为我只会抛出超出我需要的类型的传递对象。
这样就足够了:
void Receiver(Epsilon epsilon)
{
// if epsilon inherits from Epsilon, throw.
}
你能帮我解决我的问题的第一部分吗?谢谢!
【问题讨论】:
-
如果您的方法接受
Base作为参数并且不能使用Derived,那么您的类设计是错误的。这就是你需要解决的问题。 -
这是一种特殊情况,我使用反射将属性解析为查询字符串参数,我不想接受派生类,因为这些类可能包含其属性会导致非法查询字符串参数的属性相关的 API 调用。
-
我同意你的观点,虽然也许一切都应该是
sealed,但对我来说重要的是向上转换的方法。 -
然后只需编写代码,根据白名单过滤参数/值属性,该白名单取决于您打算调用的 API,并将其作为“使用这些参数调用 API”方法的一部分运行。
-
如果发现参数不在白名单中,则抛出异常。无论如何你都会扔一个,这个解决方案也涵盖了你的情况。将属性添加到
Beta并忘记您的查询会在它上面出错。我的观点是,您正在关注错误的方法,因此我让这个主题休息一下。 :)