创建匿名类型成员的联合

Pro*_*ofK 2 .net anonymous-types

怎么可能将两个或多个匿名(或可能不是匿名)类型的实例的成员联合起来,以创建一个包含所有成员的结果类型实例?

伪代码示例:

var anon1 = new {FirstName = "Bill"};
var anon2 = new {Surname = "Hicks"};
var anon3 = anon1.Union(anon2);

Debug.WriteLine(anon3.FirstName + " " + anon3.Surname);
Run Code Online (Sandbox Code Playgroud)

输出是:"比尔希克斯"

dri*_*iis 5

编译器只知道声明它的方法中的匿名类型,所以不,你不能做那样的事情.(当然你可以传递它,但它会被输入为对象).

您可以使用这两个属性声明一个新的匿名类型,但这可能不是您想要的:

var anon3 = new  { anon1.FirstName, anon2.Surname };
Run Code Online (Sandbox Code Playgroud)

使用C#4的dynamic构造可以模仿你想要的东西,但是Union的返回值将是dynamic,而不是强类型.

编辑以回应您的评论:

以下是如何使用Union如何实现Union方法的示例 dynamic

public static class AnonymousTypeExtension
{
    public static dynamic Union(this object first, params object [] others)
    {
        var allObjects = new[] {first}.Concat(others);
        var allProperties = allObjects.SelectMany(o => o.GetType().GetProperties(),
                            (o, p) => new {p.Name, Value = p.GetValue(o, null)});

        IDictionary<string,object> expando = new ExpandoObject();
        foreach(var property in allProperties.Where(p => !expando.ContainsKey(p.Name)))
            expando.Add(property.Name,property.Value);
        return expando;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将使您的示例代码工作,只需要一点点扭曲,字符串连接的结果也将是类型化的动态,这不是Debug.WriteLine的允许输入.这意味着您需要告诉编译器首先将其视为字符串(在您的实际使用场景中可能不是问题):

        var anon1 = new { FirstName = "Bill" };
        var anon2 = new { Surname = "Hicks" };
        var anon3 = anon1.Union(anon2);
        string name = anon3.FirstName + " " + anon3.Surname;
        Debug.WriteLine(name);
Run Code Online (Sandbox Code Playgroud)