【问题标题】:How to cast to an unknown Type, need to cast to a GenericType, but T is unknown如何转换为未知类型,需要转换为GenericType,但T未知
【发布时间】:2013-10-04 19:11:38
【问题描述】:

我需要从一个我不知道类型的对象调用 DeepClone() 方法。

object x = GetObject();
var x2 = x as IDeepCloneable< ?????? >;//What can I do here???
var clone = x2.DeepClone();

public interface IDeepCloneable<T>
{
    T DeepClone();
}

我尝试创建一个新的“基础”接口并将“:IDeepCloneable”添加到泛型类中。

public interface IDeepCloneable
{
   object DeepClone();
}

但在这种情况下,我需要从 T DeepClone(); 更改派生接口的方法;到新的 T DeepClone();。结果,所有已经实现 IDeepCloneable 的类都不会编译..

【问题讨论】:

  • 如果您使用的是 .NET 4.0,您可以使用 dynamic 来完成此操作
  • @Servy 我已经完成了...您也可以在这里使用Type.MakeGenericType...它将允许您在运行时对泛型进行专门化并将其分配给动态.

标签: c# reflection interface casting


【解决方案1】:

你想要一个协变接口:

public interface IDeepCloneable<out T>
{
    T DeepClone();
}

然后您可以投射到IDeepCloneable&lt;object&gt;

【讨论】:

  • 抱歉,我遗漏了一些东西。你的回答我不清楚。编译错误:类型“object”不能用作泛型类型或方法“My.IDeepCloneable”中的类型参数“T”。没有从 'object' 到 'My.IDeepCloneable' 的隐式引用转换
  • 因为对象不是IDeepCloneable - 你必须在你想被深度克隆的对象上实现接口
  • 使用您的原始示例,他的意思是您可以执行以下操作: var x = GetObject() as IDeepCloneable; var clone = x.DeepClone(); ...假设 x 具有某种形式的运行时类型 IDeepCloneable&lt;?&gt;
  • 但是“as IDeepCloneable”没有编译
  • 几点:(1)where T : IDeepCloneable&lt;T&gt; 约束似乎没有必要,如果你省略它,这个例子应该可以工作; (2) 如果T 的运行时类型是值类型(结构),这将不起作用。换句话说,如果x 的运行时类型为struct MyCloneable : IDeepCloneable&lt;MyCloneable&gt; { ... },则不能将x 转换为IDeepCloneable&lt;object&gt;
【解决方案2】:

在 C# 4.0 中,dynamic 关键字允许您通过暂停类型检查直到运行时来解决此问题:

dynamic x = GetObject();
var clone = x.DeepClone();

只要在x 上有一个方法DeepClone() 就可以正常工作

【讨论】:

  • 仅仅让DeepClone 返回object 并没有什么收获。使用非泛型接口甚至可以为您提供比这更高的编译时类型安全性,而不会限制所需的任何功能。
  • 这不会暂停类型检查;它会导致成员绑定延迟到运行时。绑定将使用与通常在编译时强制执行的规则相同的规则来应用。主要区别在于该成员将绑定到x 的运行时类型,这在编译时是未知的,实际上如果为x 的不同运行时类型调用代码,它可能会被绑定多次。
  • @Servy 你在这里得到的事实是你可能不知道T 是什么,就像我说的......我之前不得不在运行时生成的类型上这样做,这并不好玩但它有效。
  • @MikeStrobel 对我来说听起来很像在编译时暂停类型检查......
  • @Mgetz 这就是为什么我说使用 non-generic 接口没有任何好处。如果您使用非通用接口,那么您不需要知道其类型的T
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 1970-01-01
相关资源
最近更新 更多