当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C#匿名类可以实现一个接口吗?》经验,为你挑选了7个好方法。

是否可以使用匿名类型实现接口.我有一段我想要工作的代码,但不知道该怎么做.

我有几个答案要么说不,要么创建一个实现接口的类构造新的实例.这不是很理想,但我想知道是否有一种机制可以在界面上创建一个瘦动态类,这将使这个变得简单.

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 values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

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



1> HasaniH..:

不,匿名类型无法实现接口.来自C#编程指南:

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


@ArsenZahray:lambda表达式,如果使用得当,实际上提高了代码的可读性.它们在功能链中使用时特别强大,可以减少或消除对局部变量的需求.
不管怎么说,有这个东西会很高兴.如果您正在谈论代码可读性,那么lambda表达式通常不是可行的方法.如果我们正在谈论RAD,我将全部进入类似Java的匿名接口实现.顺便说一下,在某些情况下,该功能比代表更强大
@DmitryPavlov,这非常有价值.路人:[这里](https://gist.github.com/kdbanman/34baea357f6e8203f285)是精简版.
您可以通过“匿名实现类-C#的设计模式”这种方式来完成操作-http://twistedoakstudios.com/blog/Post774_anonymous-implementation-classes-a-design-pattern-for-c

2> Mia Clarke..:

虽然这可能是一个两年前的问题,虽然线程中的答案都足够真实,但我无法抗拒告诉你实际上有可能让一个匿名类实现一个接口的冲动,即使它需要一个有点创意作弊去那儿.

早在2008年,我正在为我当时的雇主编写一个自定义LINQ提供程序,有一次我需要能够从其他匿名类中告诉"我的"匿名类,这意味着让他们实现一个我可以用来键入check的接口他们.我们解决它的方法是使用方面(我们使用PostSharp),直接在IL中添加接口实现.所以,事实上,让匿名类实现接口是可行的,你只需稍微弯曲规则就可以实现.


@Gusdor我同意其他程序员很容易获得项目并编译而没有很大的困难,但这是一个可以单独解决的不同问题,而不会完全避免像postharp这样的工具或框架.您可以针对VS本身或不属于C#规范的任何其他非标准MS框架提出相同的参数.你需要那些东西,否则它会"流行".这不是IMO的问题.问题是当构建变得如此复杂以至于难以使这些东西一起正常工作时.
@Gusdor,在这种情况下,我们完全控制了构建,它总是在专用机器上运行.此外,由于我们使用的是PostSharp,而我们所做的事情在该框架内是完全合法的,只要我们确保在我们使用的构建服务器上安装了PostSharp,就没有任何东西可以真正流行.
@ZainRizvi不,它没有.据我所知,它仍在生产中.我提出的担忧对我来说似乎很奇怪,现在对我来说是蛮横的.它基本上是在说"不要使用框架,事情会破裂!".他们没有,没有什么流行,我并不感到惊讶.
现在它变得容易多了; 生成代码后无需修改IL; 只需使用[ImpromptuInterface](https://www.nuget.org/packages/ImpromptuInterface/). - 它允许您将任何对象(包括匿名类型对象)绑定到任何接口(当然,如果您尝试使用该类实际不支持的接口的一部分,则会有后期绑定异常).

3> Arne Claasse..:

将匿名类型转换为接口已经是我想要的一段时间,但不幸的是,当前的实现迫使您拥有该接口的实现.

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

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

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


[Impromptu-Interface Project](http://code.google.com/p/impromptu-interface/)将使用DLR在.NET 4.0中执行此操作,并且比Linfu更轻.

4> Jason Bowers..:

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

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

该方法可以这样使用:

class Program
{
    static void Main(string[] args)
    {
        var developer = new { Name = "Jason Bowers" };

        PrintDeveloperName(developer.DuckCast());

        Console.ReadKey();
    }

    private static void PrintDeveloperName(IDeveloper developer)
    {
        Console.WriteLine(developer.Name);
    }
}

public interface IDeveloper
{
    string Name { get; }
}



5> Marc Gravell..:

没有; 除了具有一些属性之外,不能使匿名类型执行任何操作.您需要创建自己的类型.我没有深入阅读链接文章,但看起来它使用Reflection.Emit动态创建新类型; 但是如果你把讨论限制在C#内部的事物上,你就无法做你想做的事情.


那么,这不仅仅是一个恰好是代表的财产吗?它实际上不是一种方法.

6> ICR..:

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

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

    }

    public void DoSomethingWithDummyInterface(IEnumerable values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

请注意,您需要将查询结果强制转换为接口类型.可能有更好的方法,但我找不到它.


您可以使用`values.OfType ()`而不是强制转换.它只返回集合中实际可以强制转换为该类型的对象.这一切都取决于你想要什么.

7> Nine Tails..:

具体问到的问题的答案是否定的.但你有没有看过嘲笑框架?我使用MOQ,但那里有数以百万计的MOQ,它们允许你在线实现/ stub(部分或全部)接口.例如.

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

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

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有