0

したがって、ジェネリック型 T の何千ものオブジェクトがあり、それらを取得したオブジェクトの配列にキャストしたいと考えています。そのため、プロパティ リスト T を取得し、各プロパティの値を配列の対応するオブジェクトに設定する必要があります。

for (int i = 0; reader.Read(); i++)
{
    T tmp = (T)Activator.CreateInstance(typeof(T));
    foreach (var prop in properties)
    {         
        prop.SetValue(tmp, reader.GetValue(reader.GetOrdinal(prop.Name)), null);
    }
}

リーダーは DataReader です。私が抱えている問題は、prop.SetValueが悲しいほど遅いことです (合計実行時間の 50% を消費します)。動的メソッドまたは式ツリーを使用するように言われました。式ツリーを使用してみましたが、理解したことから、設定したい値ごとに1つのツリーを生成しますが、これはあまり良くありません。したがって、動的メソッドは他のオプションです。理想的には、何度も再利用できるメソッドSetProp(object, propertyName, value)を作成する必要があります。

4

3 に答える 3

4

FastMemberを見てください。「そのまま」使用するか、すべてのコード (DynamicMethodなど) を盗みます。これはすべて、リフレクションキャッシュなどが組み込まれていることで行われます。使用例:

var accessor = TypeAccessor.Create(typeof(T)); 
for (int i = 0; reader.Read(); i++)
{
    T tmp = (T)Activator.CreateInstance(typeof(T));
    foreach (var prop in properties)
    {         
        accessor[tmp, propName] = newValue; // fill in name/value here
    }
}

代わりに、dapper-dot-net のようなものを使用します。これはそれを行い、すべての実体化を処理します (これは明らかにデータ アクセス コードであるため)。

于 2012-05-16T14:39:37.943 に答える
3

式ツリーを使用してみましたが、設定したい値ごとに 1 つのツリーを生成する必要があることを理解しましたが、これはあまり良くありません。

なぜだめですか?基本的にList<Tuple<string, Action<object>>>、 の各プロパティの式ツリーを作成 (およびコンパイル) して を構築しTます。次に、リストを繰り返し処理し、各プロパティのアイテムを取得してから、対応するアクションを呼び出します。

私はMiscUtilPropertyCopyに非常によく似たクラスを持っています - インスピレーションのためにそれを見たいと思うかもしれません。

または、.NET 4 以降では、すべてのプロパティ設定を行う単一のBlock式ツリーを構築できます。

于 2012-05-16T14:39:06.373 に答える
0

プロパティごとに 1 つの式ツリーを作成できます。
値をパラメーターとして受け取るだけです。

var instance = Expression.Parameter(typeof(T));
var value = Expression.Parameter(typeof(object));
var setter = Expression.Lambda(
    Expression.SetProperty(instance, Expression.Cast(value, prop.PropertyType)),
    instance, value
);

これらの式ツリーは、インスタンス タイプごとに 1 回作成してコンパイルします (通常は静的ジェネリック クラス内)。

あなたがそれに取り組んでいる間、おそらくActivator.CreateInstance().

于 2012-05-16T14:38:08.890 に答える