仅具有一个实现的简单接口的匿名类型

时间:2015-06-03 12:05:44

标签: c# .net interface anonymous-types

假设我有以下界面:

public interface IMyInterface {
     A MyA { get; }
     B MyB { get; }
     C MyC { get; }
}

ABC是三个不相关的类,并且不以任何方式实现IMyInterface

现在让我们假设我只有一个这个接口的实现。我可能想要创建它用于模拟目的,即使它只是由属性组成。

我设计了以下工厂:

public static class MyManagerFactory {
    public static IMyManager CreateMyManager() {
        //Return the implementation
    }
}

我不想为一个属性的实现创建一个全新的文件和类型,所以我一直在寻找一个匿名类型:

var anon = new {
    MyA = new A(),
    MyB = new B(),
    MyC = new C()
};

但我无法返回anon,因为它的类型为object,编译器无法知道我正在实现我的界面。

所以我想做一个演员:

IMyInterface casted = anon as IMyInterface;

但这也不会编译,说明:

  

无法通过引用转换,装箱转换,取消装箱转换,换行转换或空类型转换将“AnonymousType#1”类型转换为“IMyInterface”。

我认为as转换应该在运行时完成,如果(由于任何原因)失败,它只会返回null

但是这个错误是编译时间。

如何返回IMyInterface个实例?

3 个答案:

答案 0 :(得分:3)

这是不可能的,因为类型实现接口。 它只是具有界面的方法"巧合"

C#并不查看方法是否存在,它会检查类型是否定义为实现接口。

答案 1 :(得分:2)

  

我可能想要为了嘲笑目的而创建它,

     

我不想为一个属性的实现创建一个全新的文件和类型,所以我一直在寻找一个匿名类型:

如果它仅用于模拟目的,那么您只需创建该接口的嵌套私有实现,无需全新文件

public class MyClassTests
{

    private class MyDummyImplementation : IMyInterface { ... }    

    [Fact]
    public void Test()
    {
        var x = new MyDummyImplementation();
    }

}

答案 2 :(得分:1)

这可能是一个不错的功能,但目前C#不支持在匿名对象上匿名实现的接口。

如果您查找更多信息,您会看到Java具有此功能(例如,请参阅StackOverflow中的此Q& A:How can an anonymous class use "extends" or "implements"?)。

至少C#6不包含此功能。从我的角度来看,它可能非常有用,而且在我看来,这是我在C#中实现的独特Java功能。