转换为类型未知的泛型

时间:2015-03-26 20:24:03

标签: c# generics

以下代码是我所拥有的简化版本:

public class Message
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
}

public class ExtendedMessage<TExtension> : Message 
{
    public TExtension Extension { get; set; }
}

public class Processor<T> where T : Message
{
    public void Process(T message)
    {

    }
}

我将有许多类型从Message或ExtendedMessage继承。我希望能够使用Processor来处理从ExtendedMessage继承的那些&lt;&gt;以及消息。但是,这涉及为拥有它的人操纵Extension属性。

为了做到这一点,我似乎需要将消息参数强制转换为流程方法到ExtendedMessage&lt;&gt ;,如果它属于那种类型。我试图使用以下方法做到这一点:

if (IsInstanceOfGenericType(typeof(JsonModel<>), model))
{
    var dataType = message.GetType().GetGenericArguments()[0];
    Type type = typeof(ExtendedMessage<>).MakeGenericType(dataType);
    var extendedMsg = Activator.CreateInstance(type);
    //Processing using extendedMsg.Extension
}

IsInstanceOfGenericType来自此答案:Testing if object is of generic type in C#

然而,这不起作用,显然该属性不可用。是否可以在同一方法中处理这两种类型?我是否首先以正确的方式进行此操作?我想避免扩展Processor以尽可能创建一个单独的ExtendedMessageProcessor。感谢。

1 个答案:

答案 0 :(得分:0)

简单但错误的答案是使用动态:

var extension = ((dynamic)message).Extension

更好的答案是让你的扩展继承自基础

public class ExtendedMessage : Message 
{
    public ExtensionBase Extension { get; set; }
}

public abstract class ExtensionBase
{

}

...

var extendedMessage = message as ExtendedMessage;
if (extendedMessage != null)
{
    //process
}

如果这样的事情不可能并且你仍然坚持反思,那么你就不想创建一个新的消息实例。您已经拥有该消息,并且它具有您需要的属性。您应该使用Type.GetProperties()Type.GetMethods()