2011-05-08 52 views
2

考慮到泛型方法,是否可以在模板類型上設置約束以具有某些特定屬性?C#中模板類型中的必需屬性

爲了成功地編譯下面的代碼例如

public static int[] DoSomething<T> (T[] Input) 
{ 
    int[] Output = new int[Input.Length]; 

    for (int i = 0;i < Input.Length;i++) 
     Output[i] = (int)Input[i].PropertyA+(int)Input[i].PropertyB; 

    return Output; 
} 

模板類型需要實現PropertyA和PropertyB。 是否有可能以某種方式在模板類型上設置這樣的約束?

編輯: 此外還要求PropertyA和PropertyB是數字類型,以便它們可以鍵入爲int。

謝謝。

回答

5

唯一的可能性是定義T作爲從某些公知的基類派生的類型或實現公知的接口:

public interface IWellKnown 
{ 
    int PropertyA { get; } 
    int PropertyB { get; } 
} 

您的任何方法將是:

public static int[] DoSomething<T> (T[] Input) where T : IWellKnown 
{ 
    int[] Output = new int[Input.Length]; 

    for (int i = 0;i < Input.Length;i++) 
     Output[i] = Input[i].PropertyA+Input[i].PropertyB; 

    return Output; 
} 

編輯:

創建使用任何數字類型但使用數字類型的泛型方法是不可能的,因爲.NET沒有任何基類型,如Number。所以你不能只將泛型類型限制爲數字。所有的數字類型是值類型,所以你可以這樣做:

public interface IWellKnown<TData> where TData : struct 
{ 
    TData PropertyA { get; } 
    TData PropertyB { get; } 
} 

但在這種情況下,你的界面將接受任何類型的值 - 任何自定義結構,焦炭,布爾等

+0

是的你是對的,但如果我需要這些屬性通常是數字,不一定是整數。我把這個問題說錯了,對不起。不過謝謝你的回答。 – NumberFour 2011-05-08 10:08:47

0

它不可能創造這樣的限制。您應該在運行時檢查輸入併發出有用的異常錯誤消息。

但是,您可以這樣做:

public interface IWellKnown 
{ 
    int PropertyA { get; } 
    int PropertyB { get; } 
} 

public abstract class WellKnownBase<T> : IWellKnown 
{ 
    IWellKnown.PropertyA { get { return Convert(this.PropertyA); } } 
    IWellKnown.PropertyB { get { return Convert(this.PropertyB); } } 

    public T PropertyA { get; } 
    public T PropertyA { get; } 

    protected virtual int Convert(T input) { return (int)input; } 
} 

使用這樣的基類引導一個實現具體的版本,以提供一種方法來轉換爲int。顯式接口實現提供對類型訪問器的訪問,而「真實」類仍然提供原始類型。

public class WellKnownFloat : WellKnownBase<Float> {} 

會爲您提供一個float類。如果類型不是澆注料爲int你可以提供一個自定義轉換器:

public class WellKnownTimeSpan : WellKnownBase<TimeSpan> 
{ 
    protected override int Convert(TimeSpan input) 
    { 
     return (int)input.TotalMilliseconds; 
    } 
} 

順便說一句,使用LINQ和添加的要求,你可以重寫你的函數input.Select(x => x.PropertyA + x.PropertyB)).ToArray()接口。 PS:請使用VisualStudio檢查代碼,我只是在沒有編譯器支持的情況下將它寫出來;)編譯時錯誤可能很小。

相關問題