Is there a better way that can I declare an anonymous type, without resorting to create an instance of it?
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 }));
}
I dislike the hacky-looking approach taken in the first line above, but it does allow me to use the HashSet from within different scopes later.
EDIT: A second, slightly more comprehensive, example:
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 }));
}
}
In fact there is no way of doing this, an anonymous object always has some object-initialization (which is by using new
).
Anonymous types are some kind of set and forget, which means use them once - usually within a short piece of code e.g. a LINQ-expression- and then forget that they ever existed.
However you should ask yourself why you need this at all. When you need your list throughin your class give its entites a name. What do you gain by using the same anonymous type in different scopes? Be clear and precise. Thus every developer understands what your list contains and what he/she can accept from it.
So you´d better be off using a (private) struct
for this which can also be used within your method.
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 }));
}
}
If you must store query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type
However I won´t limit this to method-boundaries as described within my second paragraph.
EDIT: To answer your question if it´s possible to create an anonymous type without instantiating it, see this sentence also from MSDN:
You create anonymous types by using the new operator together with an object initializer
EDIT2: As of C#7 you can use a tuple in your list. However a tuple has at least two properties, so your first example won´t work here:
var myList = new List<(string FirstName, string LastName)>();
myList.Add(("Boaty", "McBoatface"));
Now you can check if your other list contains such a tuple:
var contained = anotherList.Contains(("Boaty", "McBoatface"));