2016-12-22 58 views
0

我想弄清楚是否有一種方法來推廣一個函數,該函數需要一個具有相似屬性的兩個不相關對象的Hashset。下面我有一些示例代碼:推廣一個函數

private IList<IDictionary<string, string>> BuildDictionary(HashSet<ClassA> ClassA) 
{ 
    IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>(); 
    foreach (var a in ClassA) 
    { 
     Dictionary<string, string> aDictionary = new Dictionary<string, string>(); 
     aDictionary.Add(a.Code, a.Code + "," + a.Name); 
     data.Add(aDictionary); 
    } 

    return data; 
} 

private IList<IDictionary<string, string>> BuildDictionary(HashSet<ClassB> ClassB) 
{ 
    IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>(); 
    foreach (var b in ClassB) 
    { 
     Dictionary<string, string> bDictionary = new Dictionary<string, string>(); 
     bDictionary.Add(b.Code, b.Code + "," + b.Name); 
     data.Add(bDictionary); 
    } 

    return data; 
} 

因此作爲顯而易見的代碼,這兩個類是不相關的,但他們都是在一個HashSet,幷包含類似的屬性(代碼名)。我嘗試過使用泛型T,但由於我沒有創建通用類T這一事實而失敗了。無論如何無需創建一個新課程就可以解決這個問題嗎?

+3

這兩個類的接口如何? – Pikoh

+0

您是否可以訪問這兩個類,以便實現一個接口? – pstrjds

+0

您可以使用反射來檢查一個類是「typeof」還是「is」,並在T:class時使用T「 – Luther

回答

3

如果您的源類是密封的或無法修改爲通用接口,那麼您可以使用所需部件的訪問器,就像在大多數LINQ查詢中可能會這樣做的那樣。

下面是一個示例實現。請注意,toKey()toMemberValue()可以更適當地命名,但這足以複製您爲任何可以指定lambda來檢索相關屬性的類所做的工作,並且不依賴於必須具有相同屬性名稱的類只要相應地寫入lambda即可。 Main()顯示了這兩種情況下使用此方法的樣子。

public IList<IDictionary<string, string>> BuildDictionary<T>(HashSet<T> sourceSet, Func<T, string> toKey, Func<T, string> toMemberValue) 
{ 
    IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>(); 

    foreach (var element in sourceSet) 
    { 
    Dictionary<string, string> newLookup = new Dictionary<string, string>(); 
    newLookup.Add(toKey(element), $"{toKey(element)},{toMemberValue(element)}"); 
    data.Add(newLookup); 
    } 

    return data; 
} 

void Main() 
{ 
    HashSet<ClassA> setOfAs = new HashSet<ClassA>(new[] { new ClassA { Code = "foo", Name = "bar" }, new ClassA { Code = "foo2", Name = "bar2" } }); 
    HashSet<ClassB> setOfBs = new HashSet<ClassB>(new[] { new ClassB { Code = "foo", Name = "bar" }, new ClassB { Code = "foo2", Name = "bar2" } }); 

    var lookupOfAs = BuildDictionary(setOfAs, x => x.Code, x => x.Name); 
    var lookupOfBs = BuildDictionary(setOfBs, x => x.Code, x => x.Name); 
} 

// Define other methods and classes here 
public class ClassA 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 

public class ClassB 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 
4

如果您擁有兩種類型的源代碼,則可以實現一個通用接口。

private IList<IDictionary<string, string>> BuildDictionary<T>(HashSet<T> someHashSetOfTs) where T : ICommon 
{ 
    IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>(); 
    foreach (var a in someHashSetOfTs) 
    { 
     Dictionary<string, string> aDictionary = new Dictionary<string, string>(); 
     aDictionary.Add(a.Code, a.Code + "," + a.Name); 
     data.Add(aDictionary); 
    } 

    return data; 
} 

接口定義

public interface ICommon { 
    string Code {get; } 
    string Name {get; } 
} 

並立即申請ICommon於這兩種類型ClassAClassB