C# 中存在对同一泛型的更多类约束的替代方法

本文关键字:约束 方法 存在 泛型 | 更新日期: 2023-09-27 17:57:03

考虑以下结构:

public class A
{
    public int Prop { get; set; }
}
public class B
{
    public int Prop { get; set; }
}
public static class Extension
{
    public static int Sum<T>(T template, int input) where T : A
    {
        return template.Prop + input;
    }
}

可以计算 Propinput 的总和,但前提是泛型T类型为 A

有没有办法在不更改类结构的情况下使此方法同时适用于AB

(我知道它们可以从相同的基类/接口派生并将泛型定义为基类型,但我无法修改它们)。我试过:

public static int Sum<T>(T template, int input) where T : A
                                                where T : B
{
    return template.Prop + input;
}

但这不起作用,它会生成:

已为类型参数"T"指定了约束子句。类型参数的所有约束都必须在单个 where 子句中指定。

编辑

我没有必要寻找两个单独类类型的通用参数,但我正在寻找一种与分配给单个参数的这两种类型相同的功能的方法。

C# 中存在对同一泛型的更多类约束的替代方法

为什么一开始就使用泛型?仅使用方法重载:

public static int Sum(A template, int input) { ... }
public static int Sum(B template, int input) { ... }

为避免重复代码,只需委托实现:

public static int Sum(A template, int input) { return add(A.Prop, input); }
public static int Sum(B template, int input) { return add(B.Prop, input); }
private static int add(int prop, int input) { ... }

阅读您的帖子,减少重复代码的唯一方法是:

public static class Extension
{
    public static int Sum(A template, int input)
    {
        return Sum(template.Prop, input);
    }
    public static int Sum(B template, int input)
    {
        return Sum(template.Prop, input);
    }
    static int Sum(int templateProp, int input) 
    {
        return templateProp + input;
    }
}

这假设您的方法中有更复杂的逻辑。

您可以创建包装类:

public class Wrapper
{
    private A a;
    private B b;        
    public Wrapper(A a)
    {
        this.a = a;
    }
    public Wrapper(B b)
    {
        this.b = b;
    }
    public int Prop { get { return (int)(a?.Prop ?? b?.Prop); } }
}
public static class Extension
{
    public static int Sum(this Wrapper template, int input)
    {
        return template.Prop + input;
    }
}

用法:

var a = new A();
var result = (new Wrapper(a)).Sum(2);
//or
var b = new B();
result = (new Wrapper(b)).Sum(2);

显式转换的帮助下,还有另一种解决方案:

public class Wrapper
{        
    public Wrapper(int Prop)
    {
        this.Prop = Prop;
    }
    public static explicit operator Wrapper(A a)
    {
        return new Wrapper(a.Prop);
    }
    public static explicit operator Wrapper(B b)
    {
        return new Wrapper(b.Prop);
    }
    public int Prop { get; set; }
}
//Extension method still the same...

用法:

var a = new A();
var result = ((Wrapper)a).Sum(2);
//or
var b = new B();
result = ((Wrapper)b).Sum(2);