2014-10-28 30 views
1

我有幾個不同的類型都具有一個共同的特性:C#方法採取的類型列表以相同的屬性

public class A { 
    public int SomeCommonProperty { get; set; } 

    /* 
    * some other stuff 
    */ 
} 

public class B { 
    public int SomeCommonProperty { get; set; } 

    /* 
    * some other stuff 
    */ 
} 

我想有需要的這些對象的列表與此屬性的方法這樣我可以遍歷列表和財產比較喜歡另一個參數:

public static List<T> MethodToTakeListOfAboveTypes<T>(this List<T> destinationList, List<T> sourceList, string someProp) 
{ 
    if (sourceList != null && sourceList.Exists(tab => tab.SomeCommonProperty == someProp)) 
    { 
    destinationList = sourceList.Where(tab => tab.SomeCommonProperty == someProp).ToList(); 
    } 
    return destinationList; 
} 

爲T沒有「SomeCommonProperty」的定義,這是有道理的上面的代碼不起作用。 我只想傳遞一個更通用的對象與該屬性,以便我不必爲每種類型創建相同的方法。我只是無法獲得正確的語法。這有意義嗎?

我知道我應該把SomeCommonProperty字段放入一個基類並繼承,但由於某種原因,這似乎不起作用。

+2

繼承是專門爲處理這種情況而設計的。你爲什麼認爲它「似乎不起作用」? – 2014-10-28 21:21:44

回答

2

我知道我應該把SomeCommonProperty字段放入基類並繼承,但由於某種原因,這似乎不起作用。

您需要添加一個通用的約束,則它會工作得很好

where T : CommonType 
4

讓你所有的類都實現了一些接口(或繼承一些基類此屬性),例如

public interface ICommonInterface 
{ 
    int SomeCommonProperty { get; set; } 
} 

然後你就可以把接口/類約束泛型參數類型:

public static List<T> MethodToTakeListOfAboveTypes<T>(   
    this List<T> destinationList, List<T> sourceList, string someProp) 
    where T: ICommonInterface 
{ 
    // ... 
} 

注意:您可以避開檢查,如果在源存在與someProp任何項目(在最壞的情況下,你將不得不枚舉sourceList兩次)。簡單地做過濾和檢查是否有任何結果

public static List<T> MethodToTakeListOfAboveTypes<T>(
    this List<T> destinationList, List<T> sourceList, string someProp) 
    where T: ICommonInterface 
{ 
    if (sourceList == null) 
     return destinationList; 

    var filtered = sourceList.Where(s => s.SomeCommonProperty == someProp).ToList(); 
    return filtered.Any() ? filtered : destinationList; 
} 
+0

在這種情況下,使用繼承而不是接口+擴展方法可能是更好的方法。 – 2014-10-28 21:30:35

1

如果基類中含有該名稱的屬性,你必須做的唯一的事情就是告訴該類型必須從基類繼承的一般方法:

public static List<T> MethodToTakeListOfAboveTypes<T>(this List<T> destinationList, List<T> sourceList, string someProp) where T : BaseClass 

注意使用where T :這實際上說T具有派生...

替換BaseClass與您的實際基類的名字。

public class BaseClass 
{ 
    public string SomeCommonProperty { get; set; } 
} 
1

創建具有該屬性的接口,每個類實現,然後添加一個約束到您的泛型方法:

public interface ICommonProperty 
{ 
    int SomeCommonProperty {get;set;} 
} 

public class A : ICommonProperty 
{ 
    public int SomeCommonProperty { get; set; } 
} 

public class B : ICommonProperty 
{ 
    public int SomeCommonProperty { get; set; } 
} 

public static List<T> MethodToTakeListOfAboveTypes<T>(this List<T> destinationList, List<T> sourceList, string someProp) where T : ICommonProperty 
0

如果你能繼承去(像你說的,你可以),你應該去做。但是,如果由於某種原因,你需要通過一大堆的對象,你沒有源和訪問一些你知道他們有物業迭代,你可以使用dynamic

class foo 
{ 
    public string myProp = "foo"; 
} 

class bar 
{ 
    public string myProp = "bar"; 
} 


class Program 
{ 
    static void Main(string[] args) 
    { 
     List<dynamic> list = new List<dynamic>(); 
     list.Add(new foo()); 
     list.Add(new bar()); 

     foreach (dynamic o in list) 
     { 
      Console.WriteLine(o.myProp); 
     } 
    } 
} 

您也可以撥打任意方法在dynamic。如果屬性/方法不存在,則會發生異常。

相關問題