Reputation: 7028
I have scenario where I need to get the collection of values of a property of class.
public class Person
{
public string Name { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public class PersonCollection : List<Person>
{
public object[] GetValues(string propertyName)
{
// best way to implement this method?
return null;
}
}
I want to avoid the much iterations. Any idea will help.
Upvotes: 3
Views: 1384
Reputation: 4683
A simple idea without using reflection would be like this:
public partial class PersonCollection: List<Person> {
public object[] GetValues(String propertyName) {
return (
from it in this
let x=
"Name"==propertyName
?it.Name
:"Property1"==propertyName
?it.Property1
:"Property2"==propertyName
?it.Property2
:default(object)
where null!=x
select x).ToArray();
}
}
But I'd rather return an IEnumerable
for not to enumerate eagerly:
public partial class PersonCollection: List<Person> {
public IEnumerable GetValues(String propertyName) {
return
from it in this
let x=
"Name"==propertyName
?it.Name
:"Property1"==propertyName
?it.Property1
:"Property2"==propertyName
?it.Property2
:default(object)
where null!=x
select x;
}
}
Upvotes: 2
Reputation: 16636
A simple solution would be one that uses LINQ's Select
method:
using System;
using System.Collections.Generic;
using System.Linq;
public class Person
{
public string Name { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public class PersonCollection : List<Person>
{
public object[] GetValues(string propertyName)
{
if (propertyName == "Name")
{
return this.Select(p => p.Name).ToArray();
}
else if (propertyName == "Property1")
{
return this.Select(p => p.Property1).ToArray();
}
else if (propertyName == "Property2")
{
return this.Select(p => p.Property1).ToArray();
}
// best way to implement this method?
return null;
}
}
You can also use expression trees to allow for a type-safe accessor lambda to be used as an argument:
public object[] GetValues(Expression<Func<Person, object>> propertyNameExpression)
{
var compiledPropertyNameExpression = propertyNameExpression.Compile();
if (propertyNameExpression.Body.NodeType == ExpressionType.MemberAccess)
{
return this.Select(compiledPropertyNameExpression).ToArray();
}
throw new InvalidOperationException("Invalid lambda specified. The lambda should select a property.");
}
You can then use this as follows:
var personNames = personCollection.GetValues(p => p.Name)
Upvotes: 2
Reputation: 3883
A bit of Linq magic:
public object[] GetValues(Expression<Func<Person, object>> exp)
{
var function = exp.Compile();
return this.Select(function).ToArray();
}
Usage:
// assuming coll in a PersonCollection
var names = coll.GetValues(p => p.Name);
Upvotes: 4
Reputation: 11326
Here's a working program
public class Person
{
public string Name { get; set; }
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public class PersonCollection : List<Person>
{
public object[] GetValues(string propertyName)
{
var result = new List<object>();
foreach (Person item in this)
{
result.Add(item.GetType().GetProperty(propertyName).GetValue(item));
}
return result.ToArray();
}
}
class Program
{
static void Main(string[] args)
{
var collection = new PersonCollection();
collection.Add(new Person(){Name = "George", Property1 = "aaa", Property2 = "bbbb"});
collection.Add(new Person(){Name = "Peter", Property1 = "ccc", Property2 = "dddd"});
var objects = collection.GetValues("Property1");
foreach (object item in objects)
{
Console.WriteLine(item.ToString());
}
Console.Read();
}
}
Upvotes: 1
Reputation: 4352
try this,
public object[] GetValues(string propertyName)
{
List<object> result = new List<object>();
PropertyInfo propertyInfo = typeof(Person).GetProperty(propertyName);
this.ForEach(person => result.Add(propertyInfo.GetValue(person)));
return result.ToArray();
}
Upvotes: 1
Reputation: 1728
use Reflection
Person P = new Person(); object obj = p.GetType().GetProperty(propertyName).GetValue(p, null);
Upvotes: 1
Reputation: 1466
If you are working with entity framework,
you can use this.GetAll();
Upvotes: 0