有可能让匿名类型实现接口吗?

我有一段代码,我想工作,但不知道如何做到这一点。

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

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);
        }
    }
}

我发现一篇文章动态接口包装描述了一种方法。这是最好的方法吗?


当前回答

不,匿名类型不能实现接口。摘自c#编程指南:

匿名类型是由一个或多个公共只读属性组成的类类型。不允许使用其他类型的类成员,如方法或事件。匿名类型不能强制转换为除对象以外的任何接口或类型。

其他回答

将匿名类型转换为接口是我一直想做的事情,但不幸的是,当前的实现迫使您拥有该接口的实现。

围绕它的最佳解决方案是使用某种类型的动态代理为您创建实现。利用优秀的林父项目你可以替代

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

with

 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);
        }
    }
}

注意,您需要将查询的结果强制转换为接口的类型。也许有更好的办法,但我找不到。

不,匿名类型不能实现接口。摘自c#编程指南:

匿名类型是由一个或多个公共只读属性组成的类类型。不允许使用其他类型的类成员,如方法或事件。匿名类型不能强制转换为除对象以外的任何接口或类型。

这个问题的答案是否定的。但是您是否一直在研究模仿框架?我使用的是MOQ,但有数百万个MOQ,它们允许你在线实现/存根(部分或全部)接口。如。

public void ThisWillWork()
{
    var source = new DummySource[0];
    var mock = new Mock<DummyInterface>();

    mock.SetupProperty(m => m.A, source.Select(s => s.A));
    mock.SetupProperty(m => m.B, source.Select(s => s.C + "_" + s.D));

    DoSomethingWithDummyInterface(mock.Object);
}

没有;匿名类型除了具有一些属性外,不能做任何事情。您需要创建自己的类型。我没有深入阅读链接的文章,但它似乎使用了反射。Emit动态创建新类型;但是如果你把讨论局限在c#内部,你就不能做你想做的事情。