我正在尝试将具有相同属性的匿名类型转换为接口,但它出现了错误:
无法将类型为'<> 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
答案 0 :(得分:4)
这是因为接口实现显式,而不是动态。
您不能仅仅因为它具有相同的成员而将对象强制转换为接口引用,该对象的类型也必须显式实现该接口。
除了object
,dynamic
(伪装成object
)或其自己的类型之外,匿名类型不能转换为任何内容,这也有点棘手,因为你不要我确切地知道这种类型(但是有......这样的黑客)。
所以不,你做不到。
你正在寻找的东西通常被称为“鸭子打字”,又名“如果它像鸭子一样行走,如果它像鸭子一样嘎嘎叫,那么无论如何,它都是 一只鸭子“。库存C#或.NET不支持此功能,但可以使用代码“模仿”。
如果你需要一个实现特定接口的对象,你必须声明一个实现接口的普通命名类型,它没有(好)方式。
现在,这篇文章仅在此之前,指的是C#编译器和/或.NET允许您执行的操作。这里还有另一个概念,即使C#编译器允许你这样做,也会使概念成为阴影。
那是意图。
界面执行以下操作:
即使您可以将接口穿过其头部,最后一部分也很难强加到某个类型上。如果我编写一个恰好与你的某个接口具有相同成员的类,如果你要将该接口连接到我的类上,那么你可以强加这些成员的相同含义吗?
不,你不能。
现在,很明显,是的方法,但没有一个是容易的,我会说在大多数情况下,它们会成为隐藏糟糕设计的黑客。
在任何情况下,为了避免这种情况,您可以通过反射构建另一种类型,同时包装并将所有成员委托给您的对象类型,以及实现此接口,在运行时
这是好的设计吗?不,绝对不是。
如果您真的想要沿着这条路走下去,您可以使用“ImpromptuInterface”nuget包,如下所示,您的代码将如下所示:
var entity = new { FileMasterId = fileMasterId }.ActLike<IHasFiles>();
但我强烈建议不要这样做。声明类型!