75

System.Typeのデフォルトコンストラクター(つまり、パラメーターのないインスタンスコンストラクター)を取得する最も効率的な方法は何ですか?

私は以下のコードの行に沿って何かを考えていましたが、それを行うためのより単純でより効率的な方法があるはずです。

Type type = typeof(FooBar)
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
type.GetConstructors(flags)
    .Where(constructor => constructor.GetParameters().Length == 0)
    .First();
4

5 に答える 5

140
type.GetConstructor(Type.EmptyTypes)
于 2008-09-26T22:30:24.260 に答える
31

実際に ConstructorInfo オブジェクトが必要な場合は、 Curt Hagenlocher's answerを参照してください。

一方、本当に実行時に からオブジェクトを作成しようとしているだけの場合はSystem.Type、参照してくださいSystem.Activator.CreateInstance-- それは将来的に保証されているだけでなく (Activator は よりも詳細を処理しますConstructorInfo.Invoke)、見苦しくもありません

于 2008-09-26T23:08:31.640 に答える
4

ジェネリック型パラメーターがある場合は、Jeff Bridgman の答えが最適です。構築したい型を表す Type オブジェクトしかない場合は、Activator.CreateInstance(Type)Alex Lyman が提案したように使用できますが、遅いと言われています (ただし、個人的にはプロファイルしていません)。

ただし、これらのオブジェクトを非常に頻繁に構築していることに気付いた場合は、動的にコンパイルされた Linq 式を使用する、より雄弁なアプローチがあります。

using System;
using System.Linq.Expressions;

public static class TypeHelper
{
    public static Func<object> CreateDefaultConstructor(Type type)
    {
        NewExpression newExp = Expression.New(type);

        // Create a new lambda expression with the NewExpression as the body.
        var lambda = Expression.Lambda<Func<object>>(newExp);

        // Compile our new lambda expression.
        return lambda.Compile();
    }
}

戻ってきた代理人に電話するだけです。Linq 式を常に再コンパイルするとコストがかかる可能性があるため、このデリゲートをキャッシュする必要がありますが、デリゲートをキャッシュして毎回再利用すると、非常に高速になります。私は個人的に、タイプ別に索引付けされた静的ルックアップ辞書を使用しています。この関数は、Type 情報しか知らないシリアライズされたオブジェクトを扱う場合に便利です。

注: 型が構築可能でない場合、または既定のコンストラクターがない場合、これは失敗する可能性があります。

于 2013-07-09T16:04:06.303 に答える
2

クラスをインスタンス化するための既定のコンストラクターのみを取得し、型を関数のジェネリック型パラメーターとして取得する場合は、次の操作を実行できます。

T NewItUp<T>() where T : new()
{
   return new T();
}
于 2013-04-16T19:31:39.080 に答える
-2

FormatterServices.GetUninitializedObject(Type)を試してみてください。これはActivator.CreateInstanceよりも優れています。

ただし、このメソッドはオブジェクトコンストラクターを呼び出さないため、ここで初期値を設定している場合、これは機能しません。MSDNでこのことを確認して くださいhttp://msdn.microsoft.com/en-us/library/system.runtime .serialization.formatterservices.getuninitializedobject.aspx

ここに別の方法があります http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx

ただし、オブジェクトにパラメーター化コンストラクターがある場合、これは失敗します

お役に立てれば

于 2008-09-27T00:33:28.533 に答える