有没有更好的方法可以声明匿名类型,而不需要创建它的实例?
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 }));
}
}
答案 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中的这句话:
您可以通过将new运算符与a一起使用来创建匿名类型 对象初始值设定项
EDIT2:从C#7开始,您可以在列表中使用元组。但是元组至少具有twp属性,所以你的第一个例子不能在这里工作:
var myList = new List<string FirstName, string LastName>();
myList.Add(("Boaty", "McBoatface"));
现在您可以检查您的其他列表是否包含这样的元组:
var contained = anotherList.Contains(("Boaty", "McBoatface"));