将匿名类型列表转换为接口列表

3

可能重复:
.NET 4.0中动态实现接口(C#)
将匿名类型转换为接口?

有没有一种方法可以将匿名类型“转换”为特定的接口?我知道我可以创建一个实现此接口的类,但我不需要这个类,我必须返回一个接口。

我需要一个没有第三方库的解决方案。

谢谢,

var result =
    (from a in context.TABLE1
     join b in context.TABLE2 on a.Table2Id equals b.Id
     select new
     {
         Table1Field1 = a.Field1,
         Table2Field1 = b.Field1,
         ....
     }).ToList<IMyClass>();

public interface IMyClass
{
    string Table1Field1 { get; set; }
    string Table1Field2 { get; set; }
    string Table2Field1 { get; set; }
}

4
这个链接可以帮助你:https://dev59.com/vGox5IYBdhLWcg3wWzN7。 - Mihai
我看到了这篇文章,但使用外部库在这里是不允许的。 - TheBoubou
1
如果你多读一点内容,你会看到Jon Skeet的回答说这是不可能的 :) - Mihai
1个回答

6
这是不可能的。为什么?因为匿名类型是一种语法糖。 匿名类型是设计时特性,意味着编译器将生成一个具有非常奇怪名称的实际类型,但它毕竟像任何其他类型一样。
不幸的是,C#没有自动实现接口。也就是说,您需要在已命名的类型中实现接口。
更新
想要解决这个限制吗?
您可以使用控制反转(使用类似于Castle Windsor的API或手动实现)。
请查看我刚刚编写的此示例代码:
public static class AnonymousExtensions
{
    public static T To<T>(this object anon)
    {
        // #1 Obtain the type implementing the whole interface
        Type implementation = Assembly.GetExecutingAssembly()
                                .GetTypes()
                                .SingleOrDefault(t => t.GetInterfaces().Contains(typeof(T)));

        // #2 Once you've the implementation type, you create an instance of it
        object implementationInstance = Activator.CreateInstance(implementation, false);

        // #3 Now's time to set the implementation properties based on
        // the anonyous type instance property values!
        foreach(PropertyInfo property in anon.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
        {
            // Has the implementation this anonymous type property?
            if(implementation.GetProperty(property.Name) != null)
            {
                // Setting the implementation instance property with the anonymous
                // type instance property's value!
                implementation.GetProperty(property.Name).SetValue(implementationInstance, property.GetValue(anon, null));
            }
        }

        return (T)implementationInstance;
    }
}

设计并实现一些接口...

// Some interface
public interface IHasText
{
    string Text { get; set; }
}

// An implementation for the interface
public class HasText : IHasText
{
    public string Text
    {
        get;
        set;
    }
}

现在在某处使用整个扩展方法!
var anonymous = new { Text = "Hello world!" };
IHasText hasTextImplementation = anonymous.To<IHasText>();

hasTextImplementation将拥有一个HasText实现的实例!换句话说:Text属性将包含Hello world!

请注意,此代码可以进行微调,以支持基类和抽象类,但我相信这已足够提供基本信息,以便您根据自己的需求进行改进。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接