2012-01-13 5 views
1

実行時にのみ認識されるプロパティのタイプを取得し、ジェネリックメソッドのタイプパラメータとして渡す必要があります。たとえば:ジェネリックメソッドに渡すプロパティタイプを取得

PropertyInfo prop = Bar.GetProperty("Property1"); 

//"type 'prop' could not be found" error 
Foo<prop.PropertyType>(); 

void Foo<T>() 
{ 
    //Stuff 
} 
class Bar 
{ 
    string Property1{get;set;} 
} 

Bar.Property1のタイプはコンパイル時に知られることはありませんので、私はFoo<string>();を行うことはできません。 Foo<dynamic>();を使用すると正しくコンパイルされて実行されますが、これが最善の方法であるとは確信できません。古いフレームワークを使用する方法があるかどうかを知りたいと思います。


うまくいけば、この詳細な例では、私の意図をより明確になります。

public void Map(TInType inObject, TOutType outObject) 
    { 
     //propertyIn, propertyOut, and converter are all strings identifying the properties/methods to be used from the inObject/Type outObject/Type. 
     SetPropertyValues<dynamic, dynamic>(inObject, outObject, propertyIn, propertyOut, converter); 
    } 
    private void SetPropertyValues<TPropIn,TPropOut>(TInType fromObject, TOutType toObject, string propertyIn, string propertyOut, string converter) 
    { 
     PropertyInfo prop1 = typeof(TInType).GetProperty(propertyIn); 
     MethodInfo converterMethod = typeof(TInType).GetMethod(converter); 
     PropertyInfo prop2 = typeof(TOutType).GetProperty(propertyOut); 

     prop2.SetValue(
      toObject, 
      CopyPropertyValue<TPropIn, TPropOut>((TPropIn)prop1.GetValue(fromObject, null), p => (TPropOut)converterMethod.Invoke(fromObject, new object[] { p })), 
      null); 
    } 
    private TPropOut CopyPropertyValue<TPropIn, TPropOut>(TPropIn InPropValue, Func<TPropIn, TPropOut> converterFunction) 
    { 
     return converterFunction(InPropValue); 
    } 

私は誰もが持っている可能性のある他の提案に開いている、またはコードはバックショット取り出されるべきであること、私の最初の質問はまだ私が最も興味を持っているものです。

+0

このメソッドをリフレクションで呼び出すことはできますが、これが本当に適切な解決策であるかどうかは疑問からは分かりません。 –

+1

この質問を参照してください:http://stackoverflow.com/questions/266115/pass-an-instantiated-system-type-as-a-type-parameter-for-a-generic-class – Ray

+0

あなたは 'Foo'一度それが何であるかを知っているタイプ 'T'と関係がありますか? 'Foo'の本当の実装は' void Foo (T val) 'のようなものですか? –

答えて

1

あなたはMakeGenericMethodを使うことができます。実際にはパフォーマンスはかなり妥当で、何を呼び出すかを明示的に定義できるため、オーバーヘッドが削減されます。 以下のように、Invokerは必要な明示的なメソッド/クラスを呼び出し、ヘルパーは実際にジェネリックコールを呼び出します。

public class GenericHelper 
{ 
    public static void DoSomethingGeneric(GenericInvokerParameters parameters) 
    { 
     var targetMethodInfo = typeof(GenericInvoker).GetMethod("DoSomethingGeneric"); 
     var genericTargetCall = targetMethodInfo.MakeGenericMethod(parameters.InvokeType); 
     genericTargetCall.Invoke(new GenericInvoker(), new[] { parameters }); 
    } 
} 

public class GenericInvoker 
{ 
    public void DoSomethingGeneric<T>(GenericInvokerParameters parameters) 
    { 
     //Call your generic class/method e.g. 
     SomeClass.SomeGenericMethod<T>(parameters.SomeValue); 
    } 
} 

public class GenericInvokerParameters 
{ 
    public GenericInvokerParameters(Type typeToInvoke, string someValue) 
    { 
     SomeValue = someValue; 
     InvokeType = typeToInvoke; 
    } 

    public string SomeValue { get; private set; } 
    public Type InvokeType { get; private set; } 
} 
1

dynamicに何か悪いことはありません。 それを使用してください。

EDITはあなたは反射がパフォーマンスの観点からビットそれは、私が好む可能性が高頻度でそのメソッドを呼び出すするつもりはないティル

dynamic

0

fooはジェネリックではありませんあなたが一般的にそれを使用していない場合。

関連する問題