C#特性请求:在匿名类型上实现接口 [英] C# feature request: implement interfaces on anonymous types

查看:156
本文介绍了C#特性请求:在匿名类型上实现接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何做这样的工作:

I am wondering what it would take to make something like this work:

using System;

class Program
{
    static void Main()
    {
        var f = new IFoo { 
                    Foo = "foo",
                    Print = () => Console.WriteLine(Foo)
            };
    }
}

interface IFoo
{
    String Foo { get; set; }
    void Print();
}

创建的匿名类型如下所示:

The anonymous type created would look something like this:

internal sealed class <>f__AnonymousType0<<Foo>j__TPar> : IFoo
{
    readonly <Foo>j__TPar <Foo>i__Field;

    public <>f__AnonymousType0(<Foo>j__TPar Foo)
    {
        this.<Foo>i__Field = Foo;
    }

    public <Foo>j__TPar Foo
    {
        get { return this.<Foo>i__Field; }
    }

    public void Print()
    {
        Console.WriteLine(this.Foo);
    }
}

有任何理由编译器无法做这样的事情?即使对于非void方法或方法,编译器应该能够从接口声明中推断类型。

Is there any reason that the compiler would be unable to do something like this? Even for non-void methods or methods that take parameters the compiler should be able to infer the types from the interface declaration.

免责声明:我意识到这是不可能的,这将是更有意义的简单地创建一个具体的类,在这个实例中我更感兴趣的理论方面。

Disclaimer: While I do realize that this is not currently possible and it would make more sense to simply create a concrete class in this instance I am more interested in the theoretical aspects of this.

推荐答案

重载成员,索引器和显式接口实现会有一些问题。

There would be a few issues with overloaded members, indexers, and explicit interface implementations.

但是,你可以定义语法

有趣的是,通过编写库,你可以很容易地使用C#3.0。基本上,您可以这样做:

Interestingly, you can get pretty close to what you want with C# 3.0 by writing a library. Basically, you could do this:

Create<IFoo>
(
    new
    {
        Foo = "foo",
        Print = (Action)(() => Console.WriteLine(Foo))
    }
);

这是非常接近你想要的。主要的区别是对Create而不是new关键字的调用,以及您需要指定一个委托类型的事实。

Which is pretty close to what you want. The primary differences are a call to "Create" instead of the "new" keyword and the fact that you need to specify a delegate type.

声明Create将如下所示:

The declaration of "Create" would look like this:

T Create<T> (object o)
{
//...
}

然后使用Reflection.Emit在运行时动态生成一个接口实现。

It would then use Reflection.Emit to generate an interface implementation dynamically at runtime.

然而,这种语法在显式接口实现和重载成员方面有问题,您无法在不更改编译器的情况下解决。

This syntax, however, does have problems with explicit interface implementations and overloaded members, that you couldn't resolve without changing the compiler.

另一种方法是使用集合初始化器而不是匿名类型。这将是这样:

An alternative would be to use a collection initializer rather than an anonymous type. That would look like this:

Create
{
    new Members<IFoo>
    {
        {"Print", ((IFoo @this)=>Console.WriteLine(Foo))},
        {"Foo", "foo"}
    }
}

这将使您能够:


  1. 通过为字符串参数指定类似IEnumerable.Current来处理显式接口实现。

  2. 定义Members.Add, t需要在初始化程序中指定委托类型。

您需要做一些事情来实现:

You would need to do a few things to implement this:


  1. 作为一个C#类型名称的小解析器。这只需要。,[],<>,ID和原始类型名称,因此您可以在几小时内完成。

  2. 所以你只为每个唯一的接口生成一个类

  3. 实现Reflection.Emit代码gen。这可能需要大约2天的时间。

这篇关于C#特性请求:在匿名类型上实现接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆