2011-11-18 76 views
12

我寫了一個泛型類如何在C#中減去兩個通用對象(T-T)(例如:DateTime - DateTime)?

public class Interval<T> where T : IComparable // for checking that Start < End 
{ 
    public T Start { get; set; } 
    public T End { get; set; } 
    ... 
} 

我使用這個類有日期時間,INT等

我需要一個時間屬性,返回像時間:

public object Duration 
{ 
    get 
    { 
     return End - Start; 
    } 
} 

但是,如果此屬性包含在我的課程中,編譯器會提出一個邏輯錯誤-運營商。

我該怎麼做才能正常達到這個目標呢,還是我應該忽略呢?

+1

編譯器如何知道您使用的類型是否定義了'-'運算符? – Oded

+0

這可能有助於:http://stackoverflow.com/questions/171664/how-to-turn-these-3-methods-into-one-using-c-sharp-generics,檢查Marc Gravells發佈的泛型算術。 – Alex

+0

可能的重複:http://stackoverflow.com/questions/5516459/constrain-type-to-allow-addition-subtraction-operations-in-c-sharp – Reddog

回答

3

試着這麼做這個:

static void Main(string[] args) 
{ 
    Tuple<int, bool> value = JustAMethod<int>(5, 3); 
    if (value.Item2) 
    { 
     Console.WriteLine(value.Item1); 
    } 
    else 
    { 
     Console.WriteLine("Can't substract."); 
    } 
} 
public static Tuple<T, bool> JustAMethod<T>(T arg1, T arg2) 
{ 
    dynamic dArg1 = (dynamic)arg1; 
    dynamic dArg2 = (dynamic)arg2; 
    dynamic ret; 
    try 
    { 
     ret = dArg1 - dArg2; 
     return new Tuple<T, bool>(ret, true); 
    } 
    catch 
    { 
     return new Tuple<T, bool>(default(T), false); 
    } 
} 

工作原理:首先,將參數轉換爲動態類型,並且可以在動態類型上輕鬆使用運算符。如果你不能使用運算符,那麼在運行時會拋出異常。因此,如果您嘗試減去兩個實際上無法減少的對象,我們將捕獲該異常並將其作爲Tuple中的第二項返回false

1

編譯器會這樣做,所以您不要編寫錯誤代碼,它是泛型的全部要點以及類型安全編程的概念。

如果你需要一個減去日期的方法寫一個接受日期的方法,並且如果你需要另一個整數,猜測你應該爲整數寫一個。泛型不在那裏,編譯器可以承擔任何類型的責任。想想看,如果我想要兩個對象之間的區別,我將如何使用泛型方法來做到這一點?

或@Reed Copsey提到你可以將一個類約束到它。

+0

是的,但這不是我的問題,我說不知道爲什麼? –

+0

我給了你一個答案'你爲int寫了一個方法,並且你爲'寫了一個'',泛型提供了類型安全性,而不是爲什麼它是這樣。 – JonH

+0

我站出來說我所說的,願意拿下@RedHat。 – JonH

7

這對於C#中的泛型是不可能的 - 至少不是直接的。長期以來,它一直是highly requested feature on Connect

您需要讓您的類型實現一些接口,該接口具有可以使用的成員並將類限制爲該類,或者使用Connect bug中列出的解決方法之一(其中沒有一個是完美的),或者一個單獨的方法,如MiscUtil's generic operators

+1

+1接口方法。 – MPelletier

1

雖然這可能看起來像一個主要的限制,但您需要記住泛型是通用的。當然,System.Int32類型可以很好地與C#的二元運算符一起工作。但是,爲了說明起見,如果<T>是自定義類或結構類型,則編譯器不能認爲它已使運算符過載了+,-,*/

4

這項工作

public object Duration 
{ 
    get 
    { 
     return (dynamic)End - (dynamic)Start; 
    } 
} 

,但沒有檢查,並緩慢

相關問題