4

I would like to make a query by using lambda select,

Like below:

public class Foo{
   public int Id {get;set;}
   public string Name {get;set;}
   public string Surname {get;set;}
}

var list = new List<Foo>();
var temp = list.Select(x=> x("Name"),("Surname"));

The property name needs to be sent as a string, I dont know how to use, I have given it for being a example. is it possible?

Edit:

Foo list :
1  A B
2  C D
3  E F
4  G H

I don't know type of generic list, I have property name such as "Name", "Surname"

I want to be like below:

Result :

A B
C D
E F
G H
7
  • This is unclear. Please give an sample input/desired output. Commented Oct 20, 2014 at 6:57
  • Try dynamic LINQ library. Hope that solves your problem. Please see the following link c-sharpcorner.com/UploadFile/deveshomar/… Commented Oct 20, 2014 at 6:57
  • Do you want to create a list of anonymous objects, with just Name or Surname, or you want to filter the list with a specific name and surname? Commented Oct 20, 2014 at 7:03
  • I have a just property names, I don't know type of generic list, I want to filter list by property names, not values. Commented Oct 20, 2014 at 7:05
  • I have displayed 2 examples, doing 2 different actions - one filtering and one creating a new list of anonymous objects having just 2 properties, Name and Surname. Commented Oct 20, 2014 at 7:07

4 Answers 4

4

The following code snippet shows 2 cases. One filtering on the list, and another creating a new list of anonymous objects, having just Name and Surname.

List<Foo> list = new List<Foo>();

var newList = list.Select(x=> new {  
                    AnyName1 = x.Name,
                    AnyName2 = x.Surname
                }); 

var filteredList = list.Select(x => x.Name == "FilteredName" && x.Surname == "FilteredSurname");

var filteredListByLinq = from cust in list
                             where cust.Name == "Name" && cust.Surname == "Surname"
                             select cust;

var filteredByUsingReflection = list.Select(c => c.GetType().GetProperty("Name").GetValue(c, null));
Sign up to request clarification or add additional context in comments.

10 Comments

I don't said property value, I said property name, I don't know type of generic list, How can I use x.Name or x.Surname ?
So you want to filter x.Name right? In that case you can use any of the 2nd and 3rd options. Unless I misunderstood what you are asking for?
After editing your question, doesn't creating a list of anonymous objects solve your problem? You want to eliminate the Id, and create new properties but having values of name and surname right?
Yes, I cannot use anonymous object, because I don't know what the list contains properties, I just know property names,
I updated my answer, having a filtered list by using property string names. You have to use reflection...
|
1

Interface

If you have access to the types in question, and if you always want to access the same properties, the best option is to make the types implement the same interface:

public interface INamable
{
  string Name { get; }
  string Surname { get; }
}

public class Foo : INamable
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Surname { get; set; }
}

This will preserve type safety and enable queries like this one:

public void ExtractUsingInterface<T>(IEnumerable<T> list) where T : INamable
{
  var names = list.Select(o => new { Name = o.Name, Surname = o.Surname });

  foreach (var n in names)
  {
    Console.WriteLine(n.Name + " " + n.Surname);
  }
}

If, for some reason, you can't alter the original type, here are two more options.

Reflection

The first one is reflection. This is Mez's answer, i'll just rephrase it with an anonymous type like in the previous solution (not sure what you need exactly):

public void ExtractUsingReflection<T>(IEnumerable<T> list)
{
  var names = list.Select(o => new
                               {
                                 Name = GetStringValue(o, "Name"),
                                 Surname = GetStringValue(o, "Surname")
                               });
  foreach (var n in names)
  {
    Console.WriteLine(n.Name + " " + n.Surname);
  }
}

private static string GetStringValue<T>(T obj, string propName)
{
  return obj.GetType().GetProperty(propName).GetValue(obj, null) as string;
}

Dynamic

The second uses dynamic:

public void ExtractUsingDynamic(IEnumerable list)
{
  var dynamicList = list.Cast<dynamic>();
  var names = dynamicList.Select(d => new
                                      {
                                        Name = d.Name,
                                        Surname = d.Surname
                                      });
  foreach (var n in names)
  {
    Console.WriteLine(n.Name + " " + n.Surname);
  }
}

With that in place, the following code:

IEnumerable<INamable> list = new List<Foo>
                             {
                               new Foo() {Id = 1, Name = "FooName1", Surname = "FooSurname1"},
                               new Foo() {Id = 2, Name = "FooName2", Surname = "FooSurname2"}
                             };
ExtractUsingInterface(list);
// IEnumerable<object> list... will be fine for both solutions below
ExtractUsingReflection(list);
ExtractUsingDynamic(list);

will produce the expected output:

FooName1 FooSurname1
FooName2 FooSurname2
FooName1 FooSurname1
FooName2 FooSurname2
FooName1 FooSurname1
FooName2 FooSurname2

I'm sure you can fiddle with that and get to what you are trying to achieve.

Comments

0
var temp = list.Select(x => x.Name == "Name" && x.Surname == "Surname");

Comments

0
var temp = list.Select(x => new {Name = x.Name, Surname = x.Surname});

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.