将具有相同属性的匿名类型转换为接口

时间:2017-01-09 10:24:49

标签: c# anonymous-types

我正在尝试将具有相同属性的匿名类型转换为接口,但它出现了错误:

无法将类型为'<> f__AnonymousType104`1 [System.Int32]'的对象转换为'IHasFiles'。

 public interface IHasFiles
 {
    int FileMasterId { get; }
 }

 var entity = new { FileMasterId = fileMasterId }.CastOrDefault<IHasFiles>();
 // This is the line where I get the error

1 个答案:

答案 0 :(得分:4)

这是因为接口实现显式,而不是动态

您不能仅仅因为它具有相同的成员而将对象强制转换为接口引用,该对象的类型也必须显式实现该接口。

除了objectdynamic(伪装成object)或其自己的类型之外,匿名类型不能转换为任何内容,这也有点棘手,因为你不要我确切地知道这种类型(但是有......这样的黑客)。

所以不,你做不到。

你正在寻找的东西通常被称为“鸭子打字”,又名“如果它像鸭子一样行走,如果它像鸭子一样嘎嘎叫,那么无论如何,它都是 一只鸭子“。库存C#或.NET不支持此功能,但可以使用代码“模仿”。

如果你需要一个实现特定接口的对象,你必须声明一个实现接口的普通命名类型,它没有(好)方式。

现在,这篇文章仅在此之前,指的是C#编译器和/或.NET允许您执行的操作。这里还有另一个概念,即使C#编译器允许你这样做,也会使概念成为阴影。

那是意图

界面执行以下操作:

  • 宣布关于实施者必须提供成员的合同
  • 宣布合同,了解用户可以期望会员可用的内容
  • 声明一份关于这些成员的意思的合同

即使您可以将接口穿过其头部,最后一部分也很难强加到某个类型上。如果我编写一个恰好与你的某个接口具有相同成员的类,如果你要将该接口连接到我的类上,那么你可以强加这些成员的相同含义吗?

不,你不能。

现在,很明显,的方法,但没有一个是容易的,我会说在大多数情况下,它们会成为隐藏糟糕设计的黑客。

在任何情况下,为了避免这种情况,您可以通过反射构建另一种类型,同时包装并将所有成员委托给您的对象类型,以及实现此接口,在运行时

这是好的设计吗?不,绝对不是。

如果您真的想要沿着这条路走下去,您可以使用“ImpromptuInterface”nuget包,如下所示,您的代码将如下所示:

var entity = new { FileMasterId = fileMasterId }.ActLike<IHasFiles>();

但我强烈建议不要这样做。声明类型!