【问题标题】:Cast to generic where type is unknown转换为类型未知的泛型
【发布时间】:2015-03-27 04:48:22
【问题描述】:

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

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 的类型。我希望能够使用处理器来处理继承自 ExtendedMessage 以及 Message 的那些。但是,这涉及为拥有它的人操作 Extension 属性。

为了做到这一点,我似乎需要将消息参数转换为 ExtendedMessage 的流程方法,如果它是那种类型的话。我尝试使用以下方法来做到这一点:

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#

但是这不起作用,显然该属性不可用。是否可以用相同的方法处理这两种类型?我首先要以正确的方式解决这个问题吗?如果可能,我想避免扩展处理器以创建单独的 ExtendedMessageProcessor。谢谢。

【问题讨论】:

  • 你的问题我不太清楚。您将如何使用Processor&lt;T&gt;.Process(T message) 中的Extension 属性?在哪里以及如何调用 Process 方法?如果您能提供一个示例,让您更清楚地了解您想要实现的目标,那将会很有帮助。
  • 您正在围绕模型创建一个 ExtendedMessage 包装器,但您没有将模型分配给 Extension,并且 extendedMsg 变量的类型是 System.Object。
  • Processor&lt;T&gt; 怎么知道TExtension 是什么类型?我认为我们需要查看更多您的代码。

标签: c# generics


【解决方案1】:

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

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    相关资源
    最近更新 更多