0

Person(クラスである)のリストがあるとします。約 20 のフィールド (名前、姓、年齢、生年月日など) が含まれています。だから私はこのリストを得ました:

var listOfPersons= MyContext.Persons.Cast<Person>();

ここで、この List を反復処理する必要があります。Person新しいフィールド (クラスには存在しません) を追加するたびに、たとえばCurrentDateTime.

新しいフィールドを使用して新しいオブジェクトを作成し、値を Person から新しい Class に「コピー & ペースト」できます。次のようなもの:

PersonNew newPerson = new PersonNew("Name", "Surname", "Age", "DateOfBirthdate", ... "CurrentDateTime");

しかし、将来 Person クラスを変更した場合、これは非常に悪いことです。では、新しいフィールドで「人を拡張」する戦略はありますか?それは Person インスタンス (それが何であれ) を取り、新しいフィールドを追加しますか?

4

4 に答える 4

1

Automapperを使用PersonNewして作成する静的メソッドを作成できます。Person

public class PersonNew : Person
{
    public static PersonNew CreateFromPerson(Person person, DateTime currentDateTime)
    {
        var newPerson = Mapper.Map<PersonNew>(person);
        newPerson.CurrentDateTime = currentDateTime;
    }
}
于 2013-03-06T16:15:46.610 に答える
0

最初に、繰り返しではなく、コレクションを射影するための拡張メソッドを使用することをお勧めします。そのように:

var newCollection = oldCollection.Select(entity => MakeNewType(entity))

第二に、新しいフィールドで「Person を拡張する」という意味が完全には明確ではありません。これを実現する方法をいくつか紹介します。

1) 新しいフィールドで別のクラスを作成し、それを古いフィールドにマップします。これは、モデルを適切なビューモデルにマップする asp.net mvc アプリケーションの一般的なシナリオです。Automapper は、これらのタイプのシナリオに役立ちます (Sławomir Rosiek anwser を参照)。

2) c# 4+ で dlr を利用します。Yuo は動的オブジェクトのインテリセンスを失いますが、関数に渡すことはできます

var newPeople = people.Select(p =>
    {
        dynamic expando = new ExpandoObject();
        expando.Id = p.Id;
        expando.FirtName = p.FirtName;
        /* ... */
        expando.CurrentDateTime = DateTime.Now;
        return expando;
    });

3) 匿名型を使用します。匿名型は別の関数に渡すことができないため、このアプローチは、単一のメソッド内でデータをすばやく射影し、結果を計算する必要がある場合に役立ちます

var newPeople = people.Select(p => new 
    { 
        Id = p.Id, 
        FirtName = p.FirtName, 
        /* ... */ 
        CurrentDateTime = DateTime.Now 
    });

どちらの場合も、新しく「作成された」プロパティにアクセスできるようになりました。

foreach(var p in newPeople)
{
    Console.WriteLine("CurrentDateTime: {0}", p.CurrentDateTime);
}

4) 実行時に完全な機能を備えた .net クラスを本当に作成する必要がある場合は、Reflection.Emitを使用できます。このシナリオは通常、動的プロキシ (実行時にのみ認識される機能を実装するサブクラス) を作成するために使用されます。エンティティ フレームワークがこれを行います。

于 2013-03-06T17:41:44.333 に答える
0

あなたが説明した解決策はうまくいくと思います。クラスを拡張せずに各人の誕生日を追跡したい場合はPerson、Dictionary オブジェクトを使用できます。

var listOfPersons = MyContext.Perons.Cast<Person>();
Dictionary<Person, DateTime> birthdays = new Dictionary<Person, DateTime>    
foreach(Person person in listOfPersons)
{
    birthdays.Add(person, getBirthday(person); 
}
于 2013-03-06T16:16:19.893 に答える
0

1 つの解決策は、クラスを作成し、クラスの別の定義にpartialフィールドを追加することです。partial

public partial class Person
{
    public string Name { get; set; }
    public string FirstName { get; set; }
    ...
}

...

public partial class Person
{
    public DateTime CurrentDateTime { get; set; }
}

...

var listOfPersons = MyContext.Persons.Cast<Person>();
foreach (var person in listOfPersons)
{
    person.CurrentDateTime = ....
}

クラスの同じインスタンスを使用することに注意してください。

于 2013-03-06T16:16:31.277 に答える