3

クラスのプロパティの値のコレクションを取得する必要があるシナリオがあります。

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

何度も繰り返すのは避けたい。どんなアイデアでも役に立ちます。

4

7 に答える 7

4

ちょっとした Linq マジック:

public object[] GetValues(Expression<Func<Person, object>> exp)
{
    var function = exp.Compile();
    return this.Select(function).ToArray();
}

使用法:

// assuming coll in a PersonCollection
var names = coll.GetValues(p => p.Name);
于 2013-06-06T10:15:23.577 に答える
2

簡単な解決策は、LINQ のSelect方法を使用するものです。

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

式ツリーを使用して、タイプ セーフなアクセサー ラムダを引数として使用できるようにすることもできます。

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

これを次のように使用できます。

var personNames = personCollection.GetValues(p => p.Name)
于 2013-06-06T10:09:01.027 に答える
2

リフレクションを使用しない単純なアイデアは次のようになります。

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

IEnumerableしかし、熱心に列挙しないように for を返したいと思います。

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;
    }
}
于 2013-06-06T10:24:58.717 に答える
1

これを試して、

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();
}
于 2013-06-06T10:12:02.117 に答える
1

リフレクションを使用

人 P = 新しい人 (); オブジェクト obj = p.GetType().GetProperty(プロパティ名).GetValue(p, null);

于 2013-06-06T10:09:08.093 に答える
1

ここに作業プログラムがあります

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();
    }
}
于 2013-06-06T10:15:06.067 に答える