9

一致するオブジェクトに対して変更されたすべてのプロパティの名前を取得したいと考えています。私はこれらの(簡略化された)クラスを持っています:

public enum PersonType { Student, Professor, Employee }

class Person {
    public string Name { get; set; }
    public PersonType Type { get; set; }
}

class Student : Person {
     public string MatriculationNumber { get; set; }
}

class Subject {
     public string Name { get; set; }
     public int WeeklyHours { get; set; }
}

class Professor : Person {
    public List<Subject> Subjects { get; set; }
}

ここで、プロパティ値が異なるオブジェクトを取得したいと思います。

List<Person> oldPersonList = ...
List<Person> newPersonList = ...
List<Difference> = GetDifferences(oldPersonList, newPersonList);

public List<Difference> GetDifferences(List<Person> oldP, List<Person> newP) {
     //how to check the properties without casting and checking 
     //for each type and individual property??
     //can this be done with Reflection even in Lists??
}

Difference最後に、次のような s のリストが必要です。

class Difference {
    public List<string> ChangedProperties { get; set; }
    public Person NewPerson { get; set; }
    public Person OldPerson { get; set; }
}

ChangedPropertiesには、変更されたプロパティの名前が含まれている必要があります。

4

5 に答える 5

3

2 つの簡単な方法から始めます。

public bool AreEqual(object leftValue, object rightValue)
{
    var left = JsonConvert.SerializeObject(leftValue);
    var right = JsonConvert.SerializeObject(rightValue);

    return left == right;
}

public Difference<T> GetDifference<T>(T newItem, T oldItem)
{
    var properties = typeof(T).GetProperties();

    var propertyValues = properties
        .Select(p => new { 
            p.Name, 
            LeftValue = p.GetValue(newItem), 
            RightValue = p.GetValue(oldItem) 
        });

    var differences = propertyValues
        .Where(p => !AreEqual(p.LeftValue, p.RightValue))
        .Select(p => p.Name)
        .ToList();

    return new Difference<T>
    {
        ChangedProperties = differences,
        NewItem = newItem,
        OldItem = oldItem
    };
}

AreEqual は、Json.Net を使用して 2 つのオブジェクトのシリアル化されたバージョンを比較するだけです。これにより、参照型と値型の扱いが異なります。

GetDifference は、渡されたオブジェクトのプロパティをチェックし、それらを個別に比較します。

相違点のリストを取得するには:

var oldPersonList = new List<Person> { 
    new Person { Name = "Bill" }, 
    new Person { Name = "Bob" }
};

var newPersonList = new List<Person> {
    new Person { Name = "Bill" },
    new Person { Name = "Bobby" }
};

var diffList = oldPersonList.Zip(newPersonList, GetDifference)
    .Where(d => d.ChangedProperties.Any())
    .ToList();
于 2013-06-21T03:38:10.607 に答える
2

誰もが常に気の利いた方法でデータを抽出するこれらの過度に一般的な方法を作成しようとします。それにはコストがかかります。

昔ながらのシンプルにしないのはなぜですか。

GetDifferences メンバー関数 Person を用意します。

 virtual List<String> GetDifferences(Person otherPerson){
   var diffs = new List<string>();
   if(this.X != otherPerson.X) diffs.add("X");
   ....
 }

継承されたクラスで。特定のプロパティをオーバーライドして追加します。AddRange 基本関数。

キス - シンプルにしてください。それを書くのに 10 分の猿のような作業が必要ですが、それが効率的で機能することはわかっています。

于 2013-06-24T15:31:51.950 に答える
0

ここに、で必要なことを行うコードがありますReflection

    public List<Difference> GetDifferences(List<Person> oldP, List<Person> newP)
    {
        List<Difference> allDiffs = new List<Difference>();
        foreach (Person oldPerson in oldP)
        {
            foreach (Person newPerson in newP)
            {
                Difference curDiff = GetDifferencesTwoPersons(oldPerson, newPerson);
                allDiffs.Add(curDiff);
            }
        }

        return allDiffs;
    }

    private Difference GetDifferencesTwoPersons(Person OldPerson, Person NewPerson)
    {
        MemberInfo[] members = typeof(Person).GetMembers();

        Difference returnDiff = new Difference();
        returnDiff.NewPerson = NewPerson;
        returnDiff.OldPerson = OldPerson;
        returnDiff.ChangedProperties = new List<string>();
        foreach (MemberInfo member in members)
        {
            if (member.MemberType == MemberTypes.Property)
            {
                if (typeof(Person).GetProperty(member.Name).GetValue(NewPerson, null).ToString() != typeof(Person).GetProperty(member.Name).GetValue(OldPerson, null).ToString())
                {
                    returnDiff.ChangedProperties.Add(member.Name);
                }
            }
        }

        return returnDiff;
    }
于 2013-06-22T17:48:08.890 に答える