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

时间:2022-01-24 05:40:55

Is it possible to have an anonymous type implement an interface. I've got a piece of code that I would like to work, but don't know how to do this.

是否可能有一个匿名类型实现一个接口。我有一段代码想要工作,但不知道怎么做。

I've had a couple of answers that either say no, or create a class that implements the interface construct new instances of that. This isn't really ideal, but I'm wondering if there is a mechanism to create a thin dynamic class on top of an interface which would make this simple.

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

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

I've found an article Dynamic interface wrapping that describes one approach. Is this the best way of doing this?

我发现了一个描述方法的动态界面包装。这是最好的方法吗?

7 个解决方案

#1


294  

No, anonymous types cannot implement an interface. From the C# programming guide:

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

Anonymous types are class types that consist of one or more public read-only properties. No other kinds of class members such as methods or events are allowed. An anonymous type cannot be cast to any interface or type except for object.

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

#2


78  

While this might be a two year old question, and while the answers in the thread are all true enough, I cannot resist the urge to tell you that it in fact is possible to have an anonymous class implement an interface, even though it takes a bit of creative cheating to get there.

虽然这可能是一个两岁大的问题,而答案在线程都足够真实,我无法抗拒的冲动要告诉你,它实际上可能是一个匿名类实现一个接口,尽管它需要创造性的欺骗。

Back in 2008 I was writing a custom LINQ provider for my then employer, and at one point I needed to be able to tell "my" anonymous classes from other anonymous ones, which meant having them implement an interface that I could use to type check them. The way we solved it was by using aspects (we used PostSharp), to add the interface implementation directly in the IL. So, in fact, letting anonymous classes implement interfaces is doable, you just need to bend the rules slightly to get there.

在2008年,我为当时的雇主编写了一个定制的LINQ提供程序,在某个时候,我需要能够从其他匿名类中分辨出“我的”匿名类,这意味着要让它们实现一个接口,我可以用它来对它们进行类型检查。我们解决它的方法是使用方面(我们使用了PostSharp),直接在IL中添加接口实现。因此,实际上,让匿名类实现接口是可行的,只需稍微修改规则即可到达。

#3


39  

Casting anonymous types to interfaces has been something I've wanted for a while but unfortunately the current implementation forces you to have an implementation of that interface.

将匿名类型转换为接口一直是我想要的,但不幸的是,当前的实现强迫您实现该接口。

The best solution around it is having some type of dynamic proxy that creates the implementation for you. Using the excellent LinFu project you can replace

最好的解决方案是使用某种类型的动态代理来为您创建实现。使用您可以替换的优秀的LinFu项目。

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

#4


12  

Anonymous types can implement interfaces via a dynamic proxy.

匿名类型可以通过动态代理实现接口。

I wrote an extension method on GitHub and a blog post http://wblo.gs/feE to support this scenario.

我在GitHub上写了一个扩展方法,并在博客上写了http://wblo。支持此方案的gs/费用。

The method can be used like this:

该方法可以这样使用:

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

#5


11  

No; an anonymous type can't be made to do anything except have a few properties. You will need to create your own type. I didn't read the linked article in depth, but it looks like it uses Reflection.Emit to create new types on the fly; but if you limit discussion to things within C# itself you can't do what you want.

没有;一个匿名类型不能做任何事情,除了有一些属性。您需要创建自己的类型。我没有深入阅读链接文章,但它看起来像使用反射。在飞行中发射,以创造新的类型;但是如果你把讨论限制在c#本身之内,你就不能做你想做的事。

#6


11  

The best solution is just not to use anonymous classes.

最好的解决方案就是不使用匿名类。

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

Note that you need to cast the result of the query to the type of the interface. There might be a better way to do it, but I couldn't find it.

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

#7


7  

The answer to the question specifically asked is no. But have you been looking at mocking frameworks? I use MOQ but there's millions of them out there and they allow you to implement/stub (partially or fully) interfaces in-line. Eg.

具体问题的答案是否定的。但是,你是否一直在研究模拟框架呢?我使用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);
}

#1


294  

No, anonymous types cannot implement an interface. From the C# programming guide:

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

Anonymous types are class types that consist of one or more public read-only properties. No other kinds of class members such as methods or events are allowed. An anonymous type cannot be cast to any interface or type except for object.

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

#2


78  

While this might be a two year old question, and while the answers in the thread are all true enough, I cannot resist the urge to tell you that it in fact is possible to have an anonymous class implement an interface, even though it takes a bit of creative cheating to get there.

虽然这可能是一个两岁大的问题,而答案在线程都足够真实,我无法抗拒的冲动要告诉你,它实际上可能是一个匿名类实现一个接口,尽管它需要创造性的欺骗。

Back in 2008 I was writing a custom LINQ provider for my then employer, and at one point I needed to be able to tell "my" anonymous classes from other anonymous ones, which meant having them implement an interface that I could use to type check them. The way we solved it was by using aspects (we used PostSharp), to add the interface implementation directly in the IL. So, in fact, letting anonymous classes implement interfaces is doable, you just need to bend the rules slightly to get there.

在2008年,我为当时的雇主编写了一个定制的LINQ提供程序,在某个时候,我需要能够从其他匿名类中分辨出“我的”匿名类,这意味着要让它们实现一个接口,我可以用它来对它们进行类型检查。我们解决它的方法是使用方面(我们使用了PostSharp),直接在IL中添加接口实现。因此,实际上,让匿名类实现接口是可行的,只需稍微修改规则即可到达。

#3


39  

Casting anonymous types to interfaces has been something I've wanted for a while but unfortunately the current implementation forces you to have an implementation of that interface.

将匿名类型转换为接口一直是我想要的,但不幸的是,当前的实现强迫您实现该接口。

The best solution around it is having some type of dynamic proxy that creates the implementation for you. Using the excellent LinFu project you can replace

最好的解决方案是使用某种类型的动态代理来为您创建实现。使用您可以替换的优秀的LinFu项目。

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

#4


12  

Anonymous types can implement interfaces via a dynamic proxy.

匿名类型可以通过动态代理实现接口。

I wrote an extension method on GitHub and a blog post http://wblo.gs/feE to support this scenario.

我在GitHub上写了一个扩展方法,并在博客上写了http://wblo。支持此方案的gs/费用。

The method can be used like this:

该方法可以这样使用:

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

#5


11  

No; an anonymous type can't be made to do anything except have a few properties. You will need to create your own type. I didn't read the linked article in depth, but it looks like it uses Reflection.Emit to create new types on the fly; but if you limit discussion to things within C# itself you can't do what you want.

没有;一个匿名类型不能做任何事情,除了有一些属性。您需要创建自己的类型。我没有深入阅读链接文章,但它看起来像使用反射。在飞行中发射,以创造新的类型;但是如果你把讨论限制在c#本身之内,你就不能做你想做的事。

#6


11  

The best solution is just not to use anonymous classes.

最好的解决方案就是不使用匿名类。

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

Note that you need to cast the result of the query to the type of the interface. There might be a better way to do it, but I couldn't find it.

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

#7


7  

The answer to the question specifically asked is no. But have you been looking at mocking frameworks? I use MOQ but there's millions of them out there and they allow you to implement/stub (partially or fully) interfaces in-line. Eg.

具体问题的答案是否定的。但是,你是否一直在研究模拟框架呢?我使用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);
}