2011-12-20 49 views
0

我有一系列的編寫方法,但我認爲有一些共同點(嗯,我知道有)。我希望看到的方法將採取兩件事,一個對象和...好吧,我不太確定第二個,但可能是一個字符串。編寫某種通用方法

該對象應該是通用的,儘管它只能來自set列表(在這種情況下,該通用性似乎是從INotifyPropertyChanging和INotifyPropertyChanged接口繼承的)。

該字符串應該是通用對象內屬性的名稱。在投入使用之前應該檢查該屬性是否存在於該對象中(它將用作通過該給定屬性比較對象的方式)。

所以我想這個過程是...通用對象傳入方法(與屬性名字符串一起)。檢查該對象是否包含該屬性。如果是這樣,繼續以某種方式訪問​​'object.PropertyName',其中'PropertyName'是提供的字符串。

我不知道它是簡單的還是可能的,甚至是明智的,但我知道它會爲我節省一些時間。

在此先感謝您提供的任何建議。

編輯:感謝迄今爲止所有的回覆傢伙。讓我澄清一些事情:

澄清的「訪問」

當我說,「......並以某種方式訪問​​‘object.PropertyName’」,我的意思是,該方法應該是能夠使用該屬性名稱,就好像它只是該對象的一個​​屬性。所以,假設傳入的字符串是「ClientName」,那麼將會有讀取的能力(可能寫入,儘管目前我不這麼認爲,因爲它只是一個檢查)object.ClientName,如果確定存在。

我試圖做

我有訪問使用LINQ SQL數據庫的WCF服務。我談到的對象是實體,由程序SQLMetal.exe生成,所以我的對象是'客戶','用戶'等類似的東西。我寫了一個採用實體列表的方法。此方法僅添加集合中不存在的實體(某些實體可能是重複的)。它通過檢查實體內的屬性(對應於數據庫的列中的數據)來確定哪些是重複的。這是我想到的財產可能是可變的。

+0

並「訪問」,意思是:讀什麼書?來寫?都?要麼...?爲了設置上下文,沒有任何方便的方法來做你所要求的...你可以使用反射,或者使用你剖析一個Expression,或者你可以同時傳遞一個get和set的委託,或者你可以傳遞後備字段作爲'ref' - 哪個選項是最合乎需要的(或者:最不希望的)取決於你想要用它做什麼**。所以......你想用它做什麼? – 2011-12-20 15:09:54

+0

你想如何訪問它?讀?寫?都? - 哈克馬克打敗了我。 – Nick 2011-12-20 15:10:48

+0

如果它不是很強類型的話,不,你不能只調用'object.ClientName'。您必須使用反射來獲取PropertyInfo對象,並使用它來查找每個對象的屬性值,如我在下面的回答中所述。 – Nick 2011-12-20 16:57:53

回答

1

這聽起來像你真的不想檢查,如果它是一個特定的類型,如果是這樣的話,那麼你就不必而且它實際上更容易不檢查類型。這顯示瞭如何檢查屬性存在,如果它是可讀可寫,並展示瞭如何使用它,它的發現之後:

private void Form1_Load(object sender, EventArgs e) 
{ 
    StringBuilder sb = new StringBuilder(); 

    PropertyInfo info = GetProperty(sb, "Capacity"); 
    //To get the value of the property, call GetValue on the PropertyInfo with the object and null parameters: 
    info.GetValue(sb, null); 
    //To set the value of the property, call SetValue on the PropertyInfo with the object, value, and null parameters: 
    info.SetValue(sb, 20, null); 
} 

private PropertyInfo GetProperty(object obj, string property) 
{ 
    PropertyInfo info = obj.GetType().GetProperty(property); 
    if (info != null && info.CanRead && info.CanWrite) 
     return info; 
    return null; 
} 

我覺得只有索引的屬性可以在C#中的參數。我相信如果你在VB中編寫了一些帶參數的屬性,並試圖在C#中引用該程序集,它們將顯示爲方法而不是屬性。

你也可以寫這樣的功能,將採取2個對象和屬性名稱的字符串,並返回這些屬性的結果一致:

private bool DoObjectsMatch(object obj1, object obj2, string propetyName) 
{ 
    PropertyInfo info1 = obj1.GetType().GetProperty(propertyName); 
    PropertyInfo info2 = obj2.GetType().GetProperty(propertyName); 
    if (info1 != null && info1.CanRead && info2 != null && info2.CanRead) 
     return info1.GetValue(obj1, null).ToString() == info2.GetValue(obj2, null).ToString(); 
    return false; 
} 

屬性的值進行比較可能會非常棘手,因爲它會將它們作爲對象進行比較,誰知道他們將如何處理平等問題。但在這種情況下,將值轉換爲字符串應該適合您。

如果你知道2個對象都是同一類型,那麼你可以把它簡化:

private bool DoObjectsMatch(object obj1, object obj2, string propetyName) 
{ 
    PropertyInfo info = obj1.GetType().GetProperty(propertyName); 
    if (info != null && info.CanRead) 
     return info.GetValue(obj1, null).ToString() == info.GetValue(obj2, null).ToString(); 
    return false; 
} 
+0

你好,尼克。感謝你的回答。儘管如此,我仍然對第二和第三代碼示例之間的差異感到困惑。 info1和info2從哪裏來的? – TheFaithfulLearner 2011-12-21 09:58:23

+0

Typo。 info1和info2都應該只是信息。我修好了它。不同的是第三個假設obj1和obj2是相同的對象類型,所以1的propertyinfo對於另一個是相同的。在第二個,他們不被認爲是相同的類型,所以它獲得兩個屬性信息。 – Nick 2011-12-21 16:28:15

1

我認爲你正在尋找的東西,如:

public void SomeMethod<T>(T object, string propName) 
    where T : INotifyPropertyChanging, INotifyPropertyChanged 
(
    var type = typeof(T); 
    var property = type.GetProperty(propName); 

    if(property == null) 
     throw new ArgumentException("Property doesn't exist", "propName"); 

    var value = property.GetValue(object, null); 
) 
相關問題