答えようとする前に、あなたがしていることは冗長に思えることを指摘しなければならないと感じています。このコードをコンストラクターに入れていると仮定すると、次のようなものが生成されます。
public class Foo
{
private int a;
private bool b;
private SomeType c;
public Foo()
{
this.a = default(int);
this.b = default(bool);
this.c = default(SomeType);
}
}
不要です。クラスが構築されると、それはすでに自動的に行われています。(実際、いくつかの簡単なテストでは、これらの割り当てがコンストラクターで明示的に行われた場合、これらの割り当てが最適化されていないことが示されていますが、JITter がそれを処理できると思います。)
第二に、default
キーワードは大部分があなたがしていることを正確に行うように設計されています: コンパイル時にタイプが不明な変数に「デフォルト」値を割り当てる方法を提供するためです。ジェネリックコードで使用するために導入されたと思いますが、自動生成されたコードはそれを使用する上でも確かに正しいです。
default
参照型の値は であるnull
ことを覚えておいてください。
this.list = default(List<int>);
新しい を構築せずList<int>
、 に設定this.list
するだけnull
です。代わりに、Type.IsValueType
プロパティを使用して値の型をデフォルト値のままにし、を使用して参照型を初期化することをお勧めしますnew
。
最後に、ここで探しているのは、クラスのIsGenericType
プロパティと対応するメソッドだと思います。Type
GetGenericArguments()
foreach (PropertyInfo property in properties)
{
if (property.Type.IsGenericType)
{
var subtypes = property.Type.GetGenericArguments();
// construct full type name from type and subtypes.
}
else
{
code += "this." + property.Name + " = default(" + property.PropertyType.Name + ")";
}
}
編集:
参照型に役立つものを構築する限り、生成されたコードで使用されている一般的な手法は、使用するクラスにパラメーターなしのコンストラクターを要求することです。クラスにパラメーターなしのコンストラクターがあるかどうかを確認するType.GetConstructor()
のは簡単Type[]
です。それが確立されたら、単に置き換えるだけで必要なものが得られます。Type.EmptyTypes
ConstructorInfo
null
default(typename)
new typename()
より一般的には、そのメソッドに任意の型の配列を指定して、一致するコンストラクターがあるかどうかを確認したり、呼び出しGetConstructors()
てそれらすべてを取得したりできます。ここで注目すべきは、 のIsPublic
、IsStatic
、およびIsGenericMethod
フィールドで、ConstructorInfo
このコードが生成されている場所から実際に呼び出すことができるものを見つけます。
ただし、解決しようとしている問題は、なんらかの制約を設定できない限り、勝手に複雑になります。1 つのオプションは、任意のコンストラクターを見つけて、次のような呼び出しを作成することです。
var line = "this." + fieldName + " = new(";
foreach ( var param in constructor.GetParameters() )
{
line += "default(" + param.ParameterType.Name + "),";
}
line = line.TrimEnd(',') + ");"
(これは説明のみを目的としていることに注意してください。ここではおそらく CodeDOM を使用するか、少なくとも StringBuilder を使用します:)
しかしもちろん、各パラメーターの適切な型名を決定するという問題があり、それ自体がジェネリックである可能性があります。また、参照型パラメーターはすべて null に初期化されます。また、選択できる任意の数のコンストラクターのどれが実際に使用可能なオブジェクトを生成するかを知る方法はありません (インスタンスを構築した直後にプロパティを設定したり、メソッドを呼び出したりすると仮定するなど、悪いことをするコンストラクターもあります)。
これらの問題をどのように解決するかは、技術的なものではありません。これと同じロジックを、各パラメーターに好きなだけ再帰的に適用できます。ユースケースについて、どれだけ複雑にする必要があるか、ユーザーにどのような制限を課すかを決定することが重要です。