在类定义中强制优先选择重载?

时间:2012-10-03 10:01:30

标签: c# overloading optional-parameters overload-resolution

我有一个通用类。它有2个构造函数。这些广泛用于我组织的代码库。

class MyClass<T> {
  MyClass() { ... }
  MyClass(T defaultValue) { ... }
}

我想添加一些功能但保持向后兼容。所以我想为每个构造函数引入一个新的布尔可选参数:

class MyClass<T> {
  MyClass(bool someFlag = false) { ... }
  MyClass(T defaultValue, bool someFlag = false) { ... }
}

但是,我已经有了一堆用法,其中T是布尔值并且传递了默认值:

class Usage {
  MyClass<bool> Booly = new MyClass<bool>(false);
}

现在,根据重载偏好定律 - 编译器将所有这些构造函数用法绑定到接受someFlag的重载,因为类型化方法“知道更好”。虽然在大多数情况下都很有意义,但这显然会影响我的向后兼容性。

我的问题很简单:我是否有语言功能可以覆盖过载首选项的默认定律,并将旧的泛型过载定义为首选过载,这样我就没有了改变所有这些用法?

当然,这种设计的一个缺点是每当我想调用第一个重载(只有someFlag参数)时 - 我必须根据C#4规范指定一个命名参数。

也欢迎对其他设计的建议,但请先尝试回答我的问题:)。

2 个答案:

答案 0 :(得分:1)

一般情况下?否。

具体......“解决方法”......在您的情况下可能会接受?将可选参数设为bool?,而不是bool

new MyClass<bool>(false)会调用defaultValue超载。

new MyClass<bool>(someFlag: false)将调用另一个重载。

也就是说,如果您有任何现有的new MyClass<bool?>(false)来电,则会改为他们

你可以通过创建一个专门用于使你的旗帜不是bool的类来克服 this

public struct FakeBool
{
    private readonly bool val;
    private FakeBool(bool val) { this.val = val; }
    public static implicit operator bool(FakeBool f) { return f.val; }
    public static implicit operator FakeBool(bool f) { return new FakeBool(f); }
}

public MyClass(FakeBool someFlag = default(FakeBool)) { ... }
public MyClass(T defaultValue, FakeBool someFlag = default(FakeBool)) { ... }

var b2 = new MyClass<bool>(true);            // calls two-argument constructor
var b1 = new MyClass<bool>(someFlag: true); // calls one-argument constructor

但这太傻了。 (另外,我无法弄清楚如何获得默认值 true - 任何想法,任何人?)

答案 1 :(得分:0)

假设您可以从每个构造函数调用Initialize()类型的方法,最好的办法是拥有三个构造函数:

MyClass() { Initialize(null, false); }
MyClass(T default, bool someFlag = false) { Initialize(default, someFlag); }
MyClass(bool someFlag)
{
   if (typeof(T) == typeof(bool))  Initialize(someFlag, false);
   else Initialize(null, someFlag);
}

private Initialize(T default, bool someFlag)
{ 
   // Do whatever
}