【问题标题】:Using generics when type is not known at compile time在编译时类型未知时使用泛型
【发布时间】:2010-11-11 12:57:19
【问题描述】:

平台:C# 2.0 WinForms

我有一个工厂类,它根据我发送的类型提供特定数据映射器的实例化,代码如下:

public static IDataMapper<T> GetMapper<T>() where T: IDto
{
    Type mapperType = MapperLocator.GetMapper(typeof(T));

    return (IDataMapper<T>)mapperType.Assembly.CreateInstance(mapperType.FullName);
}

我正在使用 DynamicProxy2 来拦截对我的 DTO 对象的方法调用。在我的拦截方法中,我试图使用 Invocation.TargetType 中的类型调用上述工厂。但是,这会出现异常:

找不到类型或命名空间名称“invocation”。

显然,这是因为任何对泛型方法的调用都需要根据我在编译时的理解明确知道类型。显然,在这种情况下我不能这样做,而且我绝对不会对我的所有 DTO 对象执行 switch 语句。

那么,你们能提出一个策略或指出我做错了什么吗?我正在尝试使其尽可能通用,以便它可以适用于我的所有对象和任何新对象以及其他项目的代码可移植性。

提前致谢!

【问题讨论】:

  • 你为什么将这个作为社区 wiki 发布?
  • 是的,这应该是一个正常的问题。
  • 我认为将帖子标记为社区 wiki 对 SO 有利。抱歉,下次我会记住这一点。

标签: c# design-patterns generics castle-dynamicproxy


【解决方案1】:

我对 DTO 不够熟悉,不知道这里是否有足够的信息来提供完整的解决方案。也就是说,another answer 大部分是正确的; C# 编译器在编译时需要类型信息。

但是,有一种方法可以解决这个问题:反射。 System.Reflection(我认为在你的情况下尤其是MethodInfo)将允许你编写一个完全通用的解决方案。

如果我正确理解了这个问题,您要做的是获取该工厂函数的 MethodInfo,用 MakeGenericMethod 替换类型,然后调用它。

【讨论】:

  • 你是个天才!谢谢楼主!
【解决方案2】:

不幸的是,没有办法摆脱这种情况; .NET C# 编译器需要在编译时知道泛型的类型;你必须找到另一种方法。

您也许可以使用装箱/拆箱和非泛型,但我不太了解您将如何实现它。或者,您可以使用System.Reflection。再说一次,我不知道该怎么做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-17
    • 2016-11-04
    • 2020-02-24
    • 2013-08-20
    • 2015-07-31
    • 2017-02-21
    • 1970-01-01
    相关资源
    最近更新 更多