2013-03-09 88 views
1

我有點困惑atm,我不認爲這可能是如此艱難,因爲那時我一定會做錯事。過去2天我現在要做的是訪問存儲在列表中的對象內的方法,但我無法得到它。在我看來,它應該是讓對象回到它的原始類型並調用方法,但我不能這樣做。存儲對象的調用方法

我一直在閱讀關於類型,泛型和反射的很多內容,但它無法獲得任何工作,所以我一直在做這一切都錯了,我需要幫助找到光!

繼承人我試圖

  Object customer = Hotel.Main.Manager.GetMainList(x); 
      Type frsttype = customer.GetType();    
      MethodInfo method = frsttype.GetMethod("GetCustomerSpecificData"); 
      MethodInfo generic = method.MakeGenericMethod(frsttype); 
      String str = generic.Invoke(method); 

最新的代碼我試圖達到的目標裏面這個方法:

  public override string GetCustomerSpecificData() 
    { 
     string strout = string.Format("{0,-5}{1,26}{2,28}{3,28}\a", ID, Name, Age, Gender); 

     string strInfo = Extra; 
     strout += (string.IsNullOrEmpty(strInfo) ? string.Empty : strInfo); 

     if (m_specialoffer) 
     { 
      strout += string.Format("\nSpecial Offer"); 
     } 
     if (IsRegularCustomer) 
     { 
      strout += (IsDangerus ? "\nIs a regular customer " : "\nIs not a regular customer."); 
     } 
     strout += Environment.NewLine + PaymentInfo(); 
     strout += (m_CarPark ? "\nHas car parked in garage." : "\nDoes not have car parked in garage."); 
     return strout; 
    } 

我希望有人能指出我在正確的方向,因爲我不要以爲我得到這個的任何地方:/

任何幫助和提示將不勝感激!所有將被回覆!

問候

+3

爲什麼你必須走這條路?你不能簡單地投給客戶,然後調用該方法嗎? '((客戶)客戶).GetCustomerSpecificData();' – rene 2013-03-09 10:26:35

+0

對不起,我不清楚。該對象可以是我在枚舉中聲明的幾種不同類型,該對象是根據它的類型創建的,然後作爲對象存儲。我需要能夠將它轉換回原來的類型,而不知道它是什麼。但是,只要我能夠將它投入到類型中,你的想法應該會更容易。 – user1501127 2013-03-09 10:43:31

+2

如果您不確定返回的類型,但是它們都實現此方法,您可以使用接口和/或基類嗎? – pwdst 2013-03-09 11:02:03

回答

2

最接近你現在有這個可能不依靠反射工作。

Object customer = Hotel.Main.Manager.GetMainList(x); 

string result=""; 
var custObj = customer as Customer; 
if (custObj !=null) 
{ 
    result = custObj.GetCustomerSpecificData(); 
} 

var specialcustObj = customer as SpecialCustomer; 
if (specialcustObj !=null) 
{ 
    result = specialcustObj.GetCustomerSpecificData(); 
} 

/* etc */ 

,或者,如果你可以改變不同類型的列表的實施有一個接口(或者替代性的(抽象)基類。

/* alternatively name it ISpecificData if you want adhere common used standards */ 
public interface SpecificData 
{ 
    string GetCustomerSpecificData(); 
} 

,併爲您的客戶和其他類,可以在列表中。

public class Customer:SpecificData 
{ 
    /* rest of implemementastion stays the same */ 
} 

你的代碼來獲得客戶會是這樣的,並將爲在實現的接口列表中每個對象的工作

Object customer = Hotel.Main.Manager.GetMainList(x); 

string result=""; 
var interfaceObj = customer as SpecificData; 
if (interfaceObj != null) 
{ 
    result = interfaceObj.GetCustomerSpecificData(); 
} 

當你知道,只有特定的接口將出現在列表中,你可以使用通用的清單,只持有對象爲特定類型:

mainlist = new List<SpecificData>(); 

,你能適應GetMainList只返回接口SpecificData

+0

謝謝Rene !!!你救了我!我已經有了類heraki,因爲你提到了一個接口<-abstract <-public類,所以只需在界面中添加契約並且以這種方式很容易。它只是跳上生活,即時通過月球!感謝您的時間!祝你有美好的一天! – user1501127 2013-03-09 13:23:13

+1

這裏只是一個小小的評論,我總是被教導,它是以「I」開頭的接口的慣例/好習慣 - 大概是爲了使代碼更容易閱讀,因此更易於維護。這是我在許多C#書籍中看到的重複模式。在上面的例子中,接口「SpecificData」將因此被命名爲「ISpecificData」。我只提到這一點,以幫助某人閱讀之前沒有使用過界面的經驗的問題。 – pwdst 2013-03-09 14:38:11

+1

在擺脫匈牙利符號的討論中,我們的指尖下有我們的IDE的推斷類型,我決定騰出一些關鍵筆劃......接口的I仍然在我們之間,所以要這樣做。 :-) – rene 2013-03-09 14:52:59

4

這兒有幾件事,你需要做的,首先讓我們看看codeyou貼

你需要牛逼問自己第一個問題是我需要使用反射,我可以改用接口還是返回我知道的類型?

你有控制GetMainList(x)嗎?如果你不能改變它,那麼它會返回一些對象更有用的東西嗎?

Object customer = Hotel.Main.Manager.GetMainList(x); 

你可以施放任何東西嗎?

其次你的目標方法不是一個通用的方法,所以下面的行不起作用。

MethodInfo generic = method.MakeGenericMethod(frsttype); 

您還調用方法不正確地調用有兩個參數,第一個是要對調用的方法和參數可以傳遞到它的目標對象。

Invoke(object obj, object[] parameters) 

要調用你的方法,你需要以下內容。

Object customer = Hotel.Main.Manager.GetMainList(x); 
Type frsttype = customer.GetType(); 
MethodInfo method = frsttype.GetMethod("GetCustomerSpecificData"); 
String str = method.Invoke(customer, null) as string; 

上有計算器,當然一些重大問題和社會維基有很多教程和例子在MSDN庫。

在.net中反射的一個很好的教程可以在下面找到。

3

我的意思是你可以很容易調用它:

Type myType =customer.GetType(); 
MethodInfo method = typeof(customer).GetMethod("GetCustomerSpecificData"); 
MethodInfo generic = method.MakeGenericMethod(myType); 
var res= generic.Invoke(this, null);