2009-07-20 25 views
0

リフレクションを使用して、一部のOpenXMLタイプ(たとえば、位置揃え)でプロパティを設定しようとしています。反射を経由して行うには、この困難をさせ何ジェネリック型と暗黙的な変換でのリフレクションの使用

// attr is an XmlAttribute, so .Name and .Value are Strings 
if (attr.Name == "Val") 
{ 
    if (element is Justification) 
    { 
     ((Justification)element).Val = (JustificationValues)Enum.Parse(typeof(JustificationValues), attr.Value); 
      return; 
    } 
    else 
    { 
     // test for dozens of other types, such as TabStop 
    } 
} 

:すべての可能性を列挙して値を割り当てることは単純明快である 1)ヴァルプロパティの型がT > EnumValue <あるので、私は知りませんEnum.Parseの最初の引数として渡す型を抽出する方法。 2)実際の列挙型からEnumValue < >型への暗黙的な変換があります。これは、リフレクションで呼び出す方法がわかりません。

私のようなものを探して終わるようにコードをしたいと思います:

PropertyInfo pInfo = element.GetType().GetProperty(attr.Name); 
Object value = ConvertToPropType(pInfo.PropertyType, attr.Value); /* this 
    would return an instance of EnumValue<JustificationValues> in this case */ 
pInfo.SetValue(element, value, null); 

どのように私はConvertToPropTypeを実装していますか?または、より良い解決策がありますか?

おかげで

編集: 私はエリカーの提案を使用して作業溶液を得たが、それは、列挙の型名は、ノードのタイプ名(「正当化」から得ることができるという便利な事実に依存している - >「JustificationValues」 )。私はまだ一般的なケースでこれを解決する方法が不思議です。

Edit2: GetGenericArgumentsは私の残りの部分を手に入れました。ありがとう。

+0

をやっている何のために十分でしたか?プロパティタイプからenum型を取得する方法を示します。 –

答えて

4

属性値が単なる文字列の場合は、文字列が特定の列挙値の値を識別する方法が既にあると思います。あなたの例では、ハードコーディングされているので、あなたが望むものか、変更したいのかは分かりません。

これは列挙型であり、どの列挙型かを知っていることを前提に、スニペットの場合と同様に、右側のボックス化された値(enum)を含むオブジェクトを取得する方法を既に知っています。

EnumValue<T>には、Tが必要なコンストラクタがあるとします。

Type genericType = typeof(EnumValue<>); 
Type concreteType = genericType.MakeGenericType(typeof(JustificationValues)); 

concreteTypeはタイプEnumValue<JustificationValues>です。

それでは、JustificationValuesパラメータと、Invokeというパラメータを受け取るコンストラクタを得ることができます。

更新

ああ、私はあなたが今やっているものを参照してください。 XML属性名を使用してC#プロパティを選択します。そのプロパティがタイプEnumValue<T>であるかどうかを検出し、Tが何であるかを調べる必要があります。

PropertyInfo p = // ... get property info 

Type t = p.GetType(); 

if (t.IsGenericType && 
    t.GetGenericTypeDefinition == typeof(EnumValue<>)) 
{ 
    Type e = t.GetGenericArguments()[0]; // get first (and only) type arg 

    // e is the enum type... 

これを試してください。

+0

一般的に列挙型はわかりませんが、要素の型によって異なります。私はMakeGenericTypeについて知りませんでしたが、タイプEnumValueからタイプTを抽出する方法を理解するまでは使用することはできません。 bmm6o

+0

私はあなたがプロパティを検索していたことを忘れていました属性名を使用します。 –

1

.Net 4.0では、遅延バインドされた暗黙または明示的変換をサポートしています。これは、オープンソースフレームワークImpromptuInterfaceで簡略化され、InvokeConvertという静的メソッドが使用されています。あなたの理想的な例では、それはこのように動作します:

PropertyInfo pInfo = element.GetType().GetProperty(attr.Name); 
Object value = Impromptu.InvokeConvert(attr.Value, pInfo.PropertyType); 
pInfo.SetValue(element, value, null); 
1

これは基本的なタイプで動作するかもしれませんが、あなたが私の答えに更新を見ました、それは私が

PropertyInfo pInfo = element.GetType().GetProperty(attr.Name); 
Object value = System.Convert.ChangeType(attr.Value, pInfo.PropertyType); 
pInfo.SetValue(element, value, null); 
関連する問題