是否可以将泛型重载限制为属性类型?

Posted

技术标签:

【中文标题】是否可以将泛型重载限制为属性类型?【英文标题】:Is it possible to restrict generic overload to property type? 【发布时间】:2013-07-31 20:28:23 【问题描述】:

问题是我能否以某种方式将泛型重载严格限制为属性类型.. 现在还不清楚,举个例子:

我有一些课

public class Obj

    public double Width  get; set; 
    public float WidthF  get; set; 

还有一些扩展

public static class TestGenericOverride

    public static void Do<TObj, TProp>(this TObj src, 
        Expression<Func<TObj, TProp>> expr, TProp val)
    
        Console.WriteLine("Do: typeof(TProp) = 0", typeof(TProp).Name);
    

这是主要的

static void Main(string[] args)

    var o = new Obj();

    o.Do(p => p.Width, 100);    //1: typeof(TProp) = Double
    o.Do(p => p.Width, 100.0);  //2: typeof(TProp) = Double

    o.Do(p => p.WidthF, 100);   //3: typeof(TProp) = Single
    o.Do(p => p.WidthF, 100.9); //4: typeof(TProp) = Double

    Console.ReadLine();

我想要的是使最后一次通话 (#4) 不可用。有可能吗?

换句话说: 如果表达式中的属性类型是浮点数,我希望只有浮点重载可用,而不是双重重载

谢谢!

【问题讨论】:

你不能。您必须进行投射,例如:o.Do(p =&gt; (double) p.WidthF, 100.9); @leppie 好像你说o.Do(p =&gt; (float) p.WidthF, 100.9),因为会自动调用双重重载。 (100.9 字面量默认为双精度)。或者我们可以写o.Do(p =&gt; p.WidthF, 100.9F) 您的问题是否仅限于 double/float 或者这是一个通用示例? 【参考方案1】:

这样就可以了:

    public static void Do<TObj, TProp, TValue>(this TObj src,
       Expression<Func<TObj, TProp>> expr, TValue val) where TValue: TProp
    
        Console.WriteLine("Do: typeof(TProp) = 0", typeof(TProp).Name);
    

新的值需要与属性的类型相同。这意味着不仅#4 不起作用,#1 和#3 也不起作用,因为 int 不是 float。不允许使用此扩展进行隐式转换。

【讨论】:

以上是关于是否可以将泛型重载限制为属性类型?的主要内容,如果未能解决你的问题,请参考以下文章

可以将泛型类型限制为枚举吗? [复制]

将泛型限制为可以为空的事物

是否存在将我的泛型方法限制为数字类型的约束?

Delphi:泛型和类型约束

Java 将泛型类型与 Void 进行比较

将泛型 T 的类型解析为 C# 中的特定接口