Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I declare a C# anonymous type without creating an instance of it?

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 }));
    }
}
like image 518
Jono Avatar asked Nov 17 '16 09:11

Jono


People also ask

What is declaration in C with example?

Declaration of a function provides the compiler with the name of the function, the number and type of arguments it takes, and its return type. For example, consider the following code, int add(int, int); Here, a function named add is declared with 2 arguments of type int and return type int.

What is type declaration in C?

A type declaration statement specifies the type, length, and attributes of objects and functions. You can assign initial values to objects. A declaration type specification (declaration_type_spec) is used in a nonexecutable statement.

How do you declare an array in C?

To create an array, define the data type (like int ) and specify the name of the array followed by square brackets []. To insert values to it, use a comma-separated list, inside curly braces: int myNumbers[] = {25, 50, 75, 100};


1 Answers

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 }));
        }
}

MSDN clearily states this:

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"));
like image 92
MakePeaceGreatAgain Avatar answered Oct 28 '22 21:10

MakePeaceGreatAgain