2010-09-09 113 views
4

我知道這可能是一個非常簡單的問題,但我現在有一個大腦放屁。我正在嘗試創建一個可以採用2種自定義類型之一的方法。基本上這個方法的主體對於兩個類型都是相同的,因爲它們都有一個Name屬性(我正在比較Name屬性以用於排序)。我應該怎麼做?如何使一種方法採取2種不同的類型

我首先想到的是剛剛與兩種類型作爲參數重載方法:

int Compare(Type1 first, Type1 second) 
int Compare (Type2 first, Type2 second) 

,但這些方法的身體結束了相同因而它似乎是一個浪費。

我的下一個想法是使用泛型,但這似乎並不正確,因爲我沒有真正使其通用,因爲它只能與2種特定類型一起使用。

說明:「自定義」類型實際上不是我的自定義類型。我的意思是他們不是內置類型。我無法控制這些類型或繼承層次結構中的內容。他們只是碰巧擁有Name屬性。

回答

7

如果兩種類型派生自相同的基礎或使用相同的接口,並且沒有其他類使用基礎和/或接口,則泛型仍然是一個選項。

int Compare<T>(T first, T second) where T : IHasName 

簡而言之,有兩個重載是要走的路。

注意:如果你有.NET 4,你可以使它成爲一個運行時的東西,並使該方法動態。

int Compare(dynamic first, dynamic second) 

在這種情況下,任何你扔它會編譯,但它會在運行時炸燬如果Name屬性不存在。個人而言,如果我不能修改類型以使用通用接口,那麼我會去重載並獲得編譯時安全。

+2

使這兩種類型實現一個共同的界面看起來像去恕我直言的方式。 – 2010-09-09 20:57:01

+0

兩者都不可能。它們不是從相同的基類派生的,這兩種類型不是由我寫的,所以我不能改變它。 – KrisTrip 2010-09-09 20:57:55

+0

即使類型不是由你寫的,你仍然可以採取超載路線? – Bertvan 2010-09-09 20:59:30

1

如果它可以只有與2種類型一起使用,然後使2重載。

+0

我確實最終走了這條路線,所以+1對你來說,但我用更多的選項標記了答案,正如其他選項可能會幫助其他人在未來更多。 – KrisTrip 2010-09-09 21:36:55

0

也許不是最好的解決辦法,但是這是我腦海: 你讓一個方法,如:

int MainCompare(Type1 first1, Type1 second1, Type2 first2, Type2 second2, bool firsttype){...} 

然後你就可以可以有兩種方法比較具有一行。

int compare(Type1 first, Type1 second){ 
    return MainCompare(first, second, null, null, true); 
} 


int compare(Type2 first, Type2 second){ 
    return MainCompare(null, null, first, second, false); 
} 

你的MainCompare只會根據它使用的類型而改變一點。

1

重載該方法將是一種很好的方法,使它只有兩種特定的類型。爲避免重複代碼,您可以在場景後面使用泛型:

public int Compare(Type1 first, Type1 second) { 
    return Compare<Type1>(first, second); 
} 

public int Compare(Type2 first, Type2 second) { 
    return Compare<Type2>(first, second); 
} 

private int Compare<T>(T first, T second) { 
    ... 
} 
+1

您仍然需要將'T'限制爲基本接口/類以便能夠調用其上的特定方法... – porges 2010-09-09 21:19:54

4

好的,我在第一個答案中完全讀錯了你的問題。這是一個更好的:)

過載是你最好的選擇。由於比較的結果只取決於Name,作出這樣做比較的方法,然後調用它:

private int Compare(string first, string second) 
{ 
    // do comparison 
} 

public int Compare(Type1 first, Type1 second) 
{ 
    return Compare(first.Name, second.Name): 
} 

public int Compare(Type2 first, Type2 second) 
{ 
    return Compare(first.Name, second.Name); 
} 

編輯:

既然你有一個以上的項目,有兩件事情可以做:

public int Compare(string first1, string second1, X first2, X second2 ... 

但是這會變得有點難看。另一種方法是提供一個投影提取值:

private int Compare<T>(T first, T second, Func<T,Tuple<string,int,TypeX,TypeY>> projection) 
{ 
    // test for first==null, second==null, etc... 

    var nicerFirst = projection(first); 
    var nicerSecond = projection(second); 

    // compare objects using nicerFirst.Item1, nicerFirst.Item2, etc. 
} 

那麼你比較看起來類似:

int Compare(Type1 first, Type1 second) 
{ 
    return Compare(first, second, x => Tuple.Create(x.Name, x.Int, x.X, x.Y)); 
} 
+0

實際上,除了名稱之外,我還做了其他比較,所以這不太合適。儘管如此+1,謝謝! – KrisTrip 2010-09-09 21:38:19

+0

我會擴大我的答案:) – porges 2010-09-09 21:47:51

0

這可能是一個過分的解決方案,但你可以使適配器的兩個班,並讓他們實現一個共同的接口:

public class MyType1 : ICommonInterface, Type1 
{ 
    // Where you can define 'Somethin' in the common interface 
    public string Something 
    { 
     get { return base.Something; } 
     set { base.Something = value; } 
    } 

    /* ... */ 
} 

public class MyType2 : ICommonInterface, Type2 
{ 
    // If there is no base.Something on Type2, you can re-name it assuming 
    // its intent is the same as Something 
    public string Something 
    { 
     get { return base.SomethingElse; } 
     set { set base.SomethingElse = value; } 
    }   
} 

然後你就可以實現基本上什麼@Anthony Pegram(+1)有:

int Compare<T> (T first, T second) where T : ICommonInterface 
{ 
    return first.Something.CompareTo(second.Something); 
} 
8

到目前爲止已經夠奇怪了沒有人發佈我認爲是最明顯的選擇:以名稱作爲比較參數。使調用者從對象中獲取名稱屬性。如果所有的方法需要使用的名稱,那麼爲什麼你傳遞的對象的其餘部分?

如果需要抽象過的「我能得到一個名字出了這種事」的概念,那麼這樣做:

例子:

int Compare(string name1, string name2) { ... whatever ... } 
int Compare<T>(T t1, T t2, Func<T, string> getName) 
{ 
    return Compare(getName(t1), getName(t2)); 
} 

現在你可以說:

Compare(car1, car2, c=>c.Name); 
Compare(employee1, employee2, e=>e.Name); 

等等。

+0

@Porges基本上發佈了這個回覆(或者非常相似)。實際上,除了名稱之外,我還做了其他比較,所以這不起作用。 +1雖然簡單。 – KrisTrip 2010-09-10 14:28:25

相關問題