2011-05-08 71 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检查代码,我只是在没有编译器支持的情况下将它写出来;)编译时错误可能很小。