考虑以下代码:
class MyClass
{
}
class MyClass2 : MyClass
{
}
private void Foo(MyClass cl)
{
//cl is actually MyClass2 instance
TestGeneric(cl);
}
private void TestGeneric<T>(T val)
{
//do smth
}
Run Code Online (Sandbox Code Playgroud)
在调用Foo()之后,TestGeneric中的T是MyClass,而不是MyClass2.如何将val视为MyClass2实例?提前致谢.
Upd:我实际上并不知道该对象是使用MyClass2 ctor 创建的,而是可以通过调用val.GetType()来推断它,所以简单的MyClass2将不起作用
它可以通过访客模式完成.这是一个很好的面向对象的方法,当你在一个处理程序类中(而不是在每个消息中)处理所有代码时,如果需要更多的消息类型,只需添加其他处理程序方法.
// Your message classes
public class MyClass : IMessage
{
// Implement acceptance of handler:
public void AcceptHandler(IMessageHandler handler)
{
handler.HandleMessage(this);
}
}
public class MyClass2 : MyClass
{
// Nothing more here
}
// Define interface of message
public interface IMessage
{
void AcceptHandler(IMessageHandler handler)
}
// Define interface of handler
public interface IMessageHandler
{
// For each type of message, define separate method
void HandleMessage(MyClass message)
void HandleMessage(MyClass2 message)
}
// Implemente actual handler implementation
public class MessageHandler : IMessageHandler
{
// Main handler method
public void HandleSomeMessage(MyClass message) // Or it could be IMessage
{
// Pass this handler to message. Since message implements AcceptHandler
// as just passing itself to handler, correct method of handler for MyClass
// or MyClass2 will be called at runtime.
message.AcceptHandler(this);
}
public void HandleMessage(MyClass message)
{
// Implement what do you need to be done for MyClass
}
public void HandleMessage(MyClass2 message)
{
// Implement what do you need to be done for MyClass2
// If code of MyClass should be run too, just call
// this.HandleMessage((MyClass)message);
}
}
Run Code Online (Sandbox Code Playgroud)
假设您可以更改Foo,但不能更改其签名,您可以这样做:
private void Foo(MyClass cl)
{
TestGeneric((dynamic)cl);
}
Run Code Online (Sandbox Code Playgroud)
TestGeneric这将解析在运行时而不是在编译时调用的版本,TestGeneric<MyClass2>当cl属于该类型时调用。
| 归档时间: |
|
| 查看次数: |
2308 次 |
| 最近记录: |