Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在类定义中强制重载的首选项?_C#_Overloading_Optional Parameters_Overload Resolution - Fatal编程技术网

C# 在类定义中强制重载的首选项?

C# 在类定义中强制重载的首选项?,c#,overloading,optional-parameters,overload-resolution,C#,Overloading,Optional Parameters,Overload Resolution,我有一个通用类。它有2个构造函数。这些在我们组织的代码库中被广泛使用 class MyClass<T> { MyClass() { ... } MyClass(T defaultValue) { ... } } class-MyClass{ MyClass(){…} MyClass(T defaultValue){…} } 我想添加一些功能,但保持向后兼容。因此,我想为每个构造函数引入一个新的布尔可选参数: class MyClass<T> { MyCla

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

class MyClass<T> {
  MyClass() { ... }
  MyClass(T defaultValue) { ... }
}
class-MyClass{
MyClass(){…}
MyClass(T defaultValue){…}
}
我想添加一些功能,但保持向后兼容。因此,我想为每个构造函数引入一个新的布尔可选参数:

class MyClass<T> {
  MyClass(bool someFlag = false) { ... }
  MyClass(T defaultValue, bool someFlag = false) { ... }
}
class-MyClass{
MyClass(bool someFlag=false){…}
MyClass(T defaultValue,bool someFlag=false){…}
}
然而,我已经有了一堆用法,其中T是布尔值,并且传递了一个默认值:

class Usage {
  MyClass<bool> Booly = new MyClass<bool>(false);
}
类用法{
MyClass Booly=新的MyClass(false);
}
现在,根据重载偏好的规律,编译器将所有此类构造函数的用法都与重载绑定,因为类型化方法“知道得更好”。虽然在大多数情况下都很合理,但这显然破坏了我的向后兼容性

我的问题很简单:是否有一种语言特性可以让我覆盖重载首选项的默认规则,并将旧的泛型重载定义为首选重载,这样我就不必更改所有此类用法

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

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

一般来说?没有

一个特定的。。。“变通办法”。。。在你的情况下,哪一种可能是可以接受的?将可选参数设置为
bool?
,而不是
bool

newmyclass(false)
将调用您的
defaultValue
重载

newmyclass(someFlag:false)
将调用另一个重载

也就是说,如果您有任何现有的
newmyclass(false)
调用,这将改变它们

您可以通过创建一个专门用于使您的标志不是布尔的类来克服这一问题:

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
公共结构FakeBool
{
私有只读布尔值;
私有FakeBool(bool val){this.val=val;}
公共静态隐式运算符bool(FakeBool f){return f.val;}
公共静态隐式运算符FakeBool(bool f){返回新的FakeBool(f);}
}
public MyClass(FakeBool someFlag=default(FakeBool)){…}
public MyClass(T defaultValue,FakeBool someFlag=default(FakeBool)){…}
var b2=新的MyClass(真);//调用两个参数构造函数
var b1=新的MyClass(someFlag:true);//调用一个参数构造函数

但这越来越愚蠢了。(另外,我不知道如何获得默认值true-任何想法,任何人?

假设您可以从每个构造函数调用一个
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
}

是否有一种语言功能可以让我覆盖过载偏好的默认规则-否@jrummell谢谢,我怀疑是这样的。呵呵,我对创造力赞不绝口,但这确实变得很愚蠢:)。虽然我很想避免类型检查,但我想我还是不得不接受@Bobson的答案。谢谢我希望避免类型检查,但我想这是最具可读性的答案。还是很好奇有没有人能想出更干净的。。