2015-11-20 118 views
1

在下面的代碼,我想打電話,我在派生類中聲明的方法:轉換/投基類型派生泛型類型

class BaseClass 
{ 
    // ... 
} 
class A<T> : BaseClass 
{ 
    public void F(T args){ //... } 
} 
class B<T> : BaseClass 
{ 
    // B<T> doesn't have method F() 
} 
///.... 
class myApplication 
{ 
    // ... 
    public void DoSomething(BaseClass arg) 
    { 
     // Now I know that arg is of type A<T> for some type T 
     // but I don't know what T is. Also declaring DoSomething 
     // as DoSomething<T>() is not an option. 
     // 
     // I would like to call (arg as A<T>).F(...) but how can I 
     // deduce T? Can it be done in any other way? 
    } 
} 

請閱讀代碼中的註釋。我該如何做這樣的事情?

+0

你試過'class myApplication '? –

+1

假設你有你要傳入F的對象,所以你不知道它的類型? –

回答

2

爲了調用該方法,可以運行下面的代碼:

class myApplication 
{ 
    // ... 
    public void DoSomething(BaseClass arg) 
    { 
     var type = arg.GetType(); 
     // Check whether a generic type was passed 
     if (type.IsGenericType) 
     { 
      var genType = type.GetGenericTypeDefinition(); 
      // Check whether it is of type A<> 
      if (genType == typeof(A<>)) 
      { 
       // Get generic argument type 
       var genArg = type.GenericTypeArguments[0]; 
       // Create a default instance; might not work under all circumstances 
       // Better to get the method parameter in another way 
       var mthArg = Activator.CreateInstance(genArg); 
       // Get method that is to be called 
       var mth = type.GetMethod("F"); 
       // Invoke method dynamically 
       mth.Invoke(arg, new object[] { mthArg }); 
      } 
     } 
    } 
} 

請注意,它T類型的參數傳遞給方法F是很重要的。你必須爲此做好準備。在我的示例中,我添加了一個對Activator.CreateInstance的調用,它要求T有一個公共的默認構造函數(我用int進行測試)。

+0

不錯!謝謝! – rashmatash