1

I have a list of type object as such

List<object> _list;

I initialize this list in a method and add a few items with properties

void CreateList()
{
_list= new List<object>();
_list.Add(new {Prop1 = 45, Prop2 = "foo", Prop3 = 4.5});
_list.Add(new {Prop1 = 14, Prop2 = "bar", Prop3 = 3.1});
}

However i now have a list of type object and i don't know it's type or the type of the elements.

I want to select a few elements based on their properties from the list using LINQ e.g. FindAll(). How do i go about this? Would it be better to create a POCO class?

4
  • Create strongly typed poco would work. Alternatives could be to use dynamic but strongly typed tends to be better than duck typing Commented Dec 23, 2017 at 15:57
  • 1
    Why it's of type object? You could've used ArrayList. The whole point of Generics it to use strongly typed object. Commented Dec 23, 2017 at 15:58
  • You should use strongly defined class, instead of anonymous, and strongly typed List, instead of the most general List<object>. Commented Dec 23, 2017 at 16:00
  • @Mahmoud i figured that using type object, if someone were to add things, it would be easier for them and not affect other code Commented Dec 23, 2017 at 16:10

2 Answers 2

8

I now have a list of type object and I don't know it's type or the type of the elements.

That's what you get for using object as element type. You still have multiple options available to you:

  • If you can create a class to represent list items, the problem is solved
  • If you can create your List in the same context where you use it, you could use var to capture the anonymous type
  • If you don't have either of these options, cast to dynamic and forego static type checking

The second option would look like this:

var list = (new[] {
    new {Prop1 = 45, Prop2 = "foo", Prop3 = 4.5}
,   new {Prop1 = 14, Prop2 = "bar", Prop3 = 3.1}
}).ToList();
...
var filtered = list.Where(x => x.Prop1==45).ToList();

The third option would look like this:

var filtered = _list
    .Cast<dynamic>()
    .Where(x => x.Prop1==45) // <<== No static type checking here
    .Cast<object>()
    .ToList();
Sign up to request clarification or add additional context in comments.

2 Comments

The second way is genius indeed! I didn't think about it. Thank you!
I can go with either the first or third option since i'm using the list elsewhere. A strongly typed class does seem like the better idea as suggested by many.
2

Since C# 7.0 you can also use the new ValueTuples.

List<(int Prop1, string Prop2, double Prop3)> _list;

void CreateList()
{
    _list = new List<(int Prop1, string Prop2, double Prop3)>();
    _list.Add((45, "foo", 4.5));  // Positional
    _list.Add((Prop1: 14, Prop2: "bar", Prop3: 3.1)); // Named
}

If the default names given by C# are sufficient you can omit the names when declaring the tuple. They will be given the names Item1, Item2 and Item3.

List<(int, string, double)> _list;

void CreateList()
{
    _list = new List<(int, string, double)>();
    _list.Add((45, "foo", 4.5));
    _list.Add((14, "bar", 3.1));
}

or

void CreateList()
{
    _list = new List<(int, string, double)> {
        (45, "foo", 4.5),
        (14, "bar", 3.1)
    };
}

Select an item by its default name:

int i = _list[0].Item1;

Decompose the tuple into local the variables int a; string b; double c;

var (a, b, c) = _list[0];

Tuples and anonymous types are great for intermediate results and for a local usage. For public APIs, prefer POCO classes, interfaces and structs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.