2011-06-01 106 views
1

有兩種對象:列表內容動態地

public class Toto 
{ 
    String test1 = ""; 
    int test2 = 0; 
} 

public class Titi 
{ 
    String testA = ""; 
    int testB = 0; 
} 

我會創造出允許我動態地檢查任何對象的內容的方法。例如:

public void checkDatas(Object o) 

在這種方法中,我將訪問test1並檢查其值,然後測試test2,然後testA和testB。就像這樣(Object)Object.getMember(new Toto(),「test1」)

我發現了反射過程的一些解釋,但沒有任何工作。

有人有想法嗎?

在此先感謝。

+0

請提供您的實際問題,這將使其更容易幫助你。 – 2011-06-01 15:53:31

回答

1

我真的不知道爲什麼你想要這樣的東西,請提供該信息,如果你有。但是,你不能做這樣的事情:

var type = o.GetType(); 
var members = type.GetMembers(BindingFlags.NonPublic|BindingFlags.Public); 
foreach(var member in members) 
{ 
    var field = type.GetField(member.Name); 
    Console.WriteLine(field.GetValue(o)); 
} 

UPDATE:使用的MemberInfo代替的PropertyInfo,你仍然應該向我們提供有關你在做什麼的信息。

+0

他們不屬性,所以GetProperties不會返回任何東西。 – Tejs 2011-06-01 15:55:20

+0

更新了示例以代替使用'MemberInfo'。 – 2011-06-01 16:32:29

2

你可以做這樣的事情,但不知道更多關於什麼是檢查每個成員「是的,我真的不能幫你更多:

public void CheckMembers(object o) 
{ 
    foreach(var member in o.GetType().GetFields()) 
    { 
     object value = member.GetValue(o); 
    } 
} 
+0

檢查每個成員意味着我想訪問它的值,以便與較好的價值進行比較。 – BaptX 2011-06-01 15:56:35

+0

那麼,你可以做'member.Name'和'member.GetValue(obj)',但這將是一個複雜的方法,將名稱查找到好值,然後查找你得到的值。這很可能是一種更好的方式。 – Tejs 2011-06-01 15:58:24

+0

o.GetType()。GetFields()。長度返回0,但我可以通過o訪問成員。 ... :( – BaptX 2011-06-01 16:00:54

1

嘗試訪問instanses相反在這樣:

public void checkDatas(Object o) 
{ 
    if (o is Toto) 
    { 
     (o as Toto).test1 = 0; 
    } 

    if (o is Titi) 
    { 
     (o as Titi).testA = ""; 
    } 
} 

請注意,我認爲這些字段是公開的。

+0

這不是一個解決方案,因爲它意味着我需要在「checkDatas」中指定每種 – BaptX 2011-06-01 16:07:35

1

而如果你知道的類型,你可以做到這一點反映使用string value = typeof(Toto).GetField("test1").GetValue(instance);,這是更有效的只是使用方法重載:

public void CheckObject(Toto toto) { } 
public void CheckObject(Titi titi) { } 

或者更好的是,有兩個對象符合接口,說ICheckable和這樣你只需要實現一個方法:

所有的
public void CheckObject(ICheckable checkable); 
+0

一個簡短的問題,如果'instance'被聲明爲'object',那麼運行時是如何計算出哪個超載運行的,它甚至可以工作嗎?我想你會得到一個編譯錯誤 – 2011-06-01 16:08:58

+0

@Tomas - The想法不是將實例作爲'object'傳遞。 – 2011-06-01 20:39:25

1

首先,面向對象編程,對象不會讓你的任何外部資源,以查看其私有字段。

對於類似的需求,例如表達對象ToString()方法的內容可以被覆蓋。請記住,對象必須決定要公開哪個值。

所以在你的情況下,你可以像這樣覆蓋ToString。

public override string ToString() 
{ 
    return String.Format("Value of test1={0}\nValue of test2={1}", test1, test2); 
} 

或嘗試像RevealValues()方法一樣實現一個接口。在後面可能要檢查的每個類中實現此接口。

3

您可以使用反射來讀取(未知)對象的成員,例如,G:

public class Toto 
{ 
    String test1 = "aaa"; 
    int test2 = 0; 
} 

// ------------- 

Toto t = new Toto(); 

var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 
foreach (FieldInfo field in t.GetType().GetFields(flags)) 
{ 
    Console.WriteLine(field.Name + " : " + field.GetValue(t)); 
} 

這將產生以下的輸出:

test1 : aaa 
test2 : 0 

注意:如果你的類有私有字段,則必須調用Type.GetFields()時指定了正確的BindingFlags,如上圖所示。

1

首先,我會嘗試在要檢查的對象中實現一些共同性。

例如,當Titi定義testA時,Toto是否有必要定義test1?如果託託和蒂蒂定義了test1,這是否可能?這樣,你將能夠創建和兩個通用接口:

public class Toto 
{ 
    private string test1 = "Hello from Toto object"; 
    public string Test1 { get { return this.test1; } } 
} 

public class Titi 
{ 
    private string test1 = "Hello from Titi object"; 
    public string Test1 { get { return this.test1; } } 
} 

現在,您可以定義一個通用的接口:

public interface ICheerfulObject 
{ 
    string Test1 { get; } 
} 

使雙方的類都實現像這樣這個接口:

public class Toto: ICheerfulObject 
{ 
    .... 
} 

pulbic class Titi: ICheerfulObject 
{ 
    .... 
} 

然後你就可以這樣做:

public void CheckData(ICheerfulObject o) 
{ 
    string data = o.Test1; 
} 

如果這種情況下是無效的,你真的需要使用反射嘗試以下操作:

public void CheckData(object o) 
{ 
    PropertyInfo property = o.GetType().GetProperty("Test1"); //Get used to using public properties. 
    string data = (string)property.GetValue(o, null); 
}