C#匿名类可以实现一个接口吗?

有可能有一个匿名types实现一个接口。 我有一段代码,我想工作,但不知道如何做到这一点。

我有几个答案,要么不说,要么创build一个实现接口的类构造新的实例。 这并不是很理想,但是我想知道是否有一种机制可以在接口之上创build一个简单的dynamic类,从而使其变得简单。

public interface DummyInterface { string A { get; } string B { get; } } public class DummySource { public string A { get; set; } public string C { get; set; } public string D { get; set; } } public class Test { public void WillThisWork() { var source = new DummySource[0]; var values = from value in source select new { A = value.A, B = value.C + "_" + value.D }; DoSomethingWithDummyInterface(values); } public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values) { foreach (var value in values) { Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B); } } } 

我发现了一篇介绍一种方法的dynamic接口封装 。 这是做这个最好的方法吗?

不,匿名types不能实现一个接口。 从C#编程指南 :

匿名types是由一个或多个公共只读属性组成的类types。 没有其他种类的成员如方法或事件被允许。 除了对象之外,匿名types不能转换为任何接口或types。

虽然这可能是一个两年前的问题,虽然线程中的答案都是真实的,但我忍不住要告诉你实际上有可能让一个匿名类实现一个接口,即使它需要一个接口有点创造性的作弊去那里。

早在2008年,我就为我当时的雇主编写了一个自定义的LINQ提供程序,并且有一次我需要能够从其他匿名类中告诉“我的”匿名类,这意味着让他们实现一个我可以用来打字检查的接口他们。 我们解决这个问题的方法是使用方面(我们使用PostSharp ),直接在IL中添加接口实现。 所以,实际上, 让匿名类实现接口是可行的 ,你只需稍微弯曲规则就可以实现。

将匿名types转换为接口已经有一段时间了,但不幸的是,当前的实现迫使你有一个接口的实现。

最好的解决scheme是有一些types的dynamic代理,为您创build实施。 使用优秀的LinFu项目,你可以取代

 select new { A = value.A, B = value.C + "_" + value.D }; 

  select new DynamicObject(new { A = value.A, B = value.C + "_" + value.D }).CreateDuck<DummyInterface>(); 

最好的解决办法就是不要使用匿名类。

 public class Test { class DummyInterfaceImplementor : IDummyInterface { public string A { get; set; } public string B { get; set; } } public void WillThisWork() { var source = new DummySource[0]; var values = from value in source select new DummyInterfaceImplementor() { A = value.A, B = value.C + "_" + value.D }; DoSomethingWithDummyInterface(values.Cast<IDummyInterface>()); } public void DoSomethingWithDummyInterface(IEnumerable<IDummyInterface> values) { foreach (var value in values) { Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B); } } } 

请注意,您需要将查询的结果转换为接口的types。 可能有更好的方法来做到这一点,但我找不到它。

没有; 一个匿名types不能做任何事情,除了有几个属性。 你将需要创build自己的types。 我没有深入地阅读链接文章,但它看起来像使用Reflection.Emit来即时创build新types; 但是如果你把讨论局限于C#本身,你就不能做你想做的事情。

匿名types可以通过dynamic代理实现接口。

我在GitHub和博客文章http://wblo.gs/feE上写了一个扩展方法来支持这种情况。;

该方法可以像这样使用:

 class Program { static void Main(string[] args) { var developer = new { Name = "Jason Bowers" }; PrintDeveloperName(developer.DuckCast<IDeveloper>()); Console.ReadKey(); } private static void PrintDeveloperName(IDeveloper developer) { Console.WriteLine(developer.Name); } } public interface IDeveloper { string Name { get; } } 

具体问题的答案是否定的。 但是你有没有在看嘲笑框架? 我使用最小起订量,但有数以百万计,他们允许你实现/存根(部分或全部)在线接口。 例如。

 public void ThisWillWork() { var source = new DummySource[0]; var mock = new Mock<DummyInterface>(); mock.SetupProperty(m => mA, source.Select(s => sA)); mock.SetupProperty(m => mB, source.Select(s => sC + "_" + sD)); DoSomethingWithDummyInterface(mock.Object); }