是否可以使用匿名类型实现接口?
我有一段我想要工作的代码,但不知道该怎么做。
我有几个答案要么说不,要么创建一个实现接口的类构造新的实例。 这不是很理想,但我想知道是否有一种机制可以在界面上创建一个瘦动态类,这将使这个变得简单。
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);
}
}
}
我发现了一篇描述一种方法的动态界面包装文章。 这是最好的方法吗?
#1楼
没有; 除了具有一些属性之外,不能使匿名类型执行任何操作。 您需要创建自己的类型。 我没有深入阅读链接文章,但看起来它使用Reflection.Emit动态创建新类型; 但是如果你把讨论限制在C#内部的事物上,你就无法做你想做的事情。
#2楼
不,匿名类型无法实现接口。 来自C#编程指南 :
匿名类型是由一个或多个公共只读属性组成的类类型。 不允许使用其他类别的成员,例如方法或事件。 除对象外,匿名类型不能强制转换为任何接口或类型。
#3楼
最好的解决方案就是不要使用匿名类。
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);
}
}
}
请注意,您需要将查询结果强制转换为接口类型。 可能有更好的方法,但我找不到它。
#4楼
具体问到的问题的答案是否定的。 但你有没有看过嘲笑框架? 我使用MOQ,但那里有数以百万计的MOQ,它们允许你在线实现/ stub(部分或全部)接口。 例如。
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);
}
#5楼
将匿名类型转换为接口已经是我想要的一段时间,但不幸的是,当前的实现迫使您拥有该接口的实现。
围绕它的最佳解决方案是使用某种类型的动态代理来为您创建实现。 使用优秀的LinFu项目,您可以替换
select new
{
A = value.A,
B = value.C + "_" + value.D
};
同
select new DynamicObject(new
{
A = value.A,
B = value.C + "_" + value.D
}).CreateDuck<DummyInterface>();
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3162161