如何在不创建C#匿名类型的情况下声明它?

时间:2016-11-17 09:43:21

标签: c# anonymous-types

有没有更好的方法可以声明匿名类型,而不需要创建它的实例?

var hashSet = new [] { new { Name = (string)null } }.Take(0).ToHashSet(); // HashSet<T>
using (new Scope())
{
    hashSet.Add(new { Name = "Boaty" });
    hashSet.Add(new { Name = "McBoatface" });
}
using (new AnotherScope())
{
    return names.Where(x => hashSet.Contains(new { x.Name }));
}

我不喜欢上面第一行中采用的看起来很糟糕的方法,但它允许我稍后在不同的范围内使用HashSet。

编辑: 第二个,稍微更全面的例子:

private IEnumerable<Person> _people;

public IEnumerable<Person> People()
{
    HashSet<T> hashSet;
    using (var new Scope())
    {
        // load a filter from somewhere else (oversimplified here to a single literal objects of an anonymous type)
        hashSet = new []
        {
            new { FirstName = "Boaty", LastName = "McBoatface" },
        }.ToHashSet();
    }
    using (var new AnotherScope())
    {
         return _people.Where(x => hashSet.Contains(new { FirstName = x.Nombre, LastName = x.Apellido }));
    }
}

1 个答案:

答案 0 :(得分:5)

实际上没有办法做到这一点,一个匿名对象总是有一些对象初始化(通过使用new)。

匿名类型是某种设置和忘记,这意味着使用它们一次 - 通常在一小段代码中,例如一个LINQ表达式 - 然后忘记它们曾经存在过。

但是你应该问问自己为什么你需要这个。如果您需要在课堂上列出名单,请为其提供名称。在不同的范围内使用相同的匿名类型可以获得什么?要清晰准确。因此,每个开发人员都了解您的列表包含的内容以及他/她可以接受的内容。

所以最好不要使用(私人)struct,这也可以在你的方法中使用。

class CyClass
{
    private struct Person { public string Name; }

    HashSet<Person> hashSet = new HashSet<Person>();

    ...

        using (var firstScope = new Scope())
        {
            hashSet.Add(new Person { Name = "Boaty" });
            hashSet.Add(new Person { Name = "McBoatface" });
        }

        using (var secondScope = new AnotherScope())
        {
            return names.Where(x => hashSet.Contains(new Person{ x.Name }));
        }
}

MSDN clearily states this:

  

如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类而不是匿名类型

但是我不会将其限制为方法边界,如我的第二段所述。

编辑:如果可以创建一个匿名类型而不实例化它来回答你的问题,请参阅MSDN中的这句话:

  

您可以通过将new运算符与a一起使用来创建匿名类型   对象初始值设定项

EDIT2:从C#7开始,您可以在列表中使用元组。但是元组至少具有twp属性,所以你的第一个例子不能在这里工作:

var myList = new List<string FirstName, string LastName>();
myList.Add(("Boaty", "McBoatface"));

现在您可以检查您的其他列表是否包含这样的元组:

var contained = anotherList.Contains(("Boaty", "McBoatface"));