子类实例的基类句柄。有没有一种优雅的方法可以在运行时获取子类类型?
这就是我目前的做法:
ref class Base abstract {};
ref class ConcreteClass1 : public Base {};
ref class ConcreteClass2 : public Base {};
(...and even more...)
void DoStuff(Base ^base)
{
System::Type ^type = base->GetType();
System::String ^name = type->Name;
if(name == "ConcreteClass1")
DoOtherStuff((ConcreteClass1 ^) base);
else if(name == "ConcreteClass2")
DoOtherStuff((ConcreteClass2 ^) base);
(...and even more...)
}
有没有更“优雅”的方式来做到这一点?
按照我的方法,我必须为每个新的具体类添加一个新的 else if,这让我感觉自己就像 thedailywtf.com 上的示例之一。
This is how I do it currently:
ref class Base abstract {};
ref class ConcreteClass1 : public Base {};
ref class ConcreteClass2 : public Base {};
(...and even more...)
void DoStuff(Base ^base)
{
System::Type ^type = base->GetType();
System::String ^name = type->Name;
if(name == "ConcreteClass1")
DoOtherStuff((ConcreteClass1 ^) base);
else if(name == "ConcreteClass2")
DoOtherStuff((ConcreteClass2 ^) base);
(...and even more...)
}
Is there a more "elegant" way to do this?
With my approach, I have to add a new else if for every new Concrete Class, which makes me feel like one of the examples on thedailywtf.com.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,您可以做的一件简单的事情就是比较直接类型而不是使用字符串和类型名称:
但是,这有相当多的“代码味道”。通常,使用抽象类的全部目的是允许多态性 - 如果您可以使 DoOtherStuff 成为每种类型的虚拟函数,您可以这样做:
并且将为您调用适当的方法...
Well, one simple thing you could do to make this more elegant would be to compare the types directly instead of using strings and type names:
However, this has quite a bit of "code smell" to it. Typically, the entire point of using abstract classes is to allow for polymorphism - if you can make DoOtherStuff a virtual function on each type, you could just do:
And the appropriate method will get called for you...
如果您的设计将有关
ConcreteClass1
特殊之处的所有知识限制在ConcreteClass1
内,那就更优雅了。您是否可以在基类中拥有一个 Process() 函数,每个函数都从基类继承,并让它执行您的 if 主体将执行的任何操作,包括调用 DoOtherStuff(this)DoOtherStuff(this)代码>?这将有更好的封装,并且当您添加更多类时,您不会更改调用代码,因为它只是调用base->Process()
并依赖于多态性。It is more elegant if your design confines all the knowledge about what makes a
ConcreteClass1
special insideConcreteClass1
. Could you have aProcess()
function in the base class that they each inherit from the base, and have it just do whatever your if bodies would do, including callingDoOtherStuff(this)
? That would have better encapsulation, and when you added more classes you wouldn't change your calling code, because it would just be callingbase->Process()
and relying on polymorphism.我发现,比 if 语句更好的设计是使用调度表——本质上是一个从“类型”到函数指针/委托的字典。如果子类负责将自身注册到表中,那么您的调度函数就像:
并且要添加新的调度,它只需要在表中注册自身 - 无需更新代码。这可以避免维护“if”聚合,如果您需要调用多个函数,您可以将调度表映射到更复杂的类型。
A better design than if statements, I find, is to use a dispatch table -- essentially a Dictionary from 'type' to function pointer / delegate. If the child class is responsible for registering itself to the table, then your dispatch function is simply something like :
and to add a new dispatch, it just needs to register itself in the table - no code updating required. This avoids maintaining the 'if' aggregate, and if you ever need to call more than one function you can make your dispatch table map to a more complex type.