猿问

带有字符串参数的构造函数和带有对象参数的相同重载

我的类目前有两个构造函数,它们是重载:

public CustomRangeValidationAttribute(string value) {}

public CustomRangeValidationAttribute(object value) {}

这似乎工作正常:当我使用string第一个构造函数调用该方法时,当我使用不同的值时,例如 an integeror boolean,第二个构造函数被调用。

我假设有一个规则可以强制特定类型匹配到更特定的重载中,从而防止

var c = new CustomRangeValidationAttrubute("test");

从调用对象重载。

这是“安全代码”,还是应该(或可以)改进代码?我有一种唠叨的感觉,这不是最佳做法。


翻翻过去那场雪
浏览 219回答 3
3回答

largeQ

一旦有更多派生类型签名的重载,编译器将始终选择您提供的最具体类型。话虽如此,除非有人这样做,否则new CustomRangeValidationAttrubute((object)"test")如果您将字符串传递给CustomRangeValidationAttrubute始终带有stringin 参数的构造函数,则将被选择。关于这是否是不好的做法,如果我没有看到您的特定用例,我无法确定,请记住您传递给的每个值类型都new CustomRangeValidationAttrubute(object)将被装箱,这很糟糕,因为它给 GC 和更何况你会失去类型安全。

红颜莎娜

您有两个重载,它们仅在引用类型上有所不同,并且引用类型之间存在层次关系,因此一个可以转换为另一个。在这种情况下,您真的应该确保在选择更广泛的重载时代码在逻辑上的行为相同,但引用结果是更派生的类型1,2。那是你集中注意力的地方。当然,如果您能坚持这条规则,通常会发现派生程度更高的重载不是必需的,而只是在更广泛的方法中进行特殊处理。1特别是因为,正如 vc74 在评论中指出的,重载决议(通常,忽略dynamic)是在编译时基于编译时类型3 完成的。2这符合重载的相同广泛原则。不要重载,选择哪一个会导致逻辑上不同的结果。如果你表现出不同的行为,不要给它们同一个名字(对于构造函数,这可能意味着分成两个单独的类,可能有一个共享的基类,如果这是你打算做的)3我很欣赏这是一个属性,所以你期望只有编译时间是相关的,但我仍然会在可能的情况下在这里听取一般原则。

叮当猫咪

我解决此代码的方法是将重载移动到具有单独方法而不是原始构造函数的新抽象类:public CustomRangeValidationStringAttribute(string value) {}public CustomRangeValidationGenericAttribute(object value) {}在从这个新基类继承的两个类中,每个类都使用自己的方法,创建两个不同的属性以供选择,[CustomRangeValidationString] 和 [CustomRangeValidationGeneric]。
随时随地看视频慕课网APP
我要回答