简体   繁体   English

具有字符串参数的构造函数和具有object参数的相同重载

[英]Constructor with string parameter and identical overload with object parameter

My class currently has two constructors, which are overloads: 我的类目前有两个构造函数,它们是重载:

public CustomRangeValidationAttribute(string value) {}

and

public CustomRangeValidationAttribute(object value) {}

this appears to be working correctly: When I call the method using a string the first constructor is called, when I use different values, for example an integer or boolean , the second constructor is called. 这似乎工作正常:当我使用string调用方法时,第一个构造函数被调用,当我使用不同的值,例如integerboolean ,第二个构造函数被调用。

I assume there is a rule to force specific type matches into the more specific overload, preventing 我假设有一个规则强制特定类型匹配进入更具体的重载,防止

var c = new CustomRangeValidationAttrubute("test");

from calling the object-overload. 从调用对象过载。

Is this "safe code", or should (or can) the code be improved? 这是“安全代码”,还是应该(或可以)改进代码? I have a nagging feeling this is not the best practice. 我有一种唠叨的感觉,这不是最好的做法。

Once there is overload with signature of more derived type the compiler will always choose most concrete type you provide. 一旦出现带有更多派生类型签名的重载,编译器将始终选择您提供的大多数具体类型。

That being said, unless someone does new CustomRangeValidationAttrubute((object)"test") if you pass string to CustomRangeValidationAttrubute always constructor with string in it's parameter will be chosen. 话虽这么说,除非有人做了new CustomRangeValidationAttrubute((object)"test")如果你将字符串传递给CustomRangeValidationAttrubute始终选择带有string构造函数。

About if this is bad practice, I can't tell for sure if I don't see your specific use case, just keep in mind every value type you pass to new CustomRangeValidationAttrubute(object) will be boxed and this is bad as it puts pressure to the GC and whats more you will loose type safety. 如果这是不好的做法,我无法确定我是否看不到您的具体用例,请记住,您传递给new CustomRangeValidationAttrubute(object)每个值类型都将被装箱,这是不好的,因为它放置对GC的压力和更多你将失去类型安全。

You have two overloads which only vary in the reference types and there's a hierarchical relationship between the reference types, such that one may be cast to the other. 您有两个重载,这些重载仅在引用类型中有所不同,并且引用类型之间存在层次关系,因此可以将其转换为另一个。

In such a circumstance, you really ought to make sure that the code behaves the same logically when the broader overload is selected but the reference turns out to be of the more derived type 1,2 . 在这种情况下,当选择更广泛的重载但参考结果是更多派生类型1,2时,您确实应该确保代码在逻辑上的行为相同。 That is where to focus your attention. 是集中注意力的地方。 Of course, if you can stick by this rule, often it'll turn out that the more derived overload isn't required and can just be special-cased within the broader method. 当然,如果你坚持这个规则,通常会发现不需要更多派生的重载,并且可以更广泛的方法中使用特殊的重载。


1 Especially because, as vc74 points out in a comment, overload resolution (generally, ignoring dynamic ) is done at compile time based on compile-time types 3 . 1特别是因为,正如vc74在注释中指出的那样,在编译时基于编译时类型3完成重载决策(通常忽略dynamic )。

2 And this fits the same broad principal for overloads. 2这适用于过载的相同广泛原则。 Don't have overloads where which one is selected leads to logically different results. 没有选择一个选项导致逻辑上不同的结果的重载。 If you're exhibiting different behaviours, don't give them the same name (for constructors, that may mean splitting into two separate classes, possibly with a shared base class, if that's what you intend to do) 如果你展示了不同的行为,不要给它们相同的名称(对于构造函数,这可能意味着分成两个单独的类,可能有一个共享的基类,如果这是你打算做的)

3 I appreciate that this is for an attribute and so you're expecting only compile-time to be relevant, but I'd still hew to the general principal here, where possible. 3我很欣赏这是一个属性,所以你只希望编译时是相关的,但我仍然会在这里尽可能地跟普通校长一起。

The way I resolved this code was by moving the overloads to a new abstract class with separate methods instead of the the original constructors: 我解决这个代码的方法是通过使用单独的方法而不是原始构造函数将重载移动到新的抽象类:

public CustomRangeValidationStringAttribute(string value) {}

public CustomRangeValidationGenericAttribute(object value) {}

In the two classes inheriting from this new base class each use their own method, creating two different attributes to choose from, [CustomRangeValidationString] and [CustomRangeValidationGeneric]. 在从这个新基类继承的两个类中,每个类都使用自己的方法,创建两个不同的属性供您选择,[CustomRangeValidationString]和[CustomRangeValidationGeneric]。

You could use a generic class. 您可以使用泛型类。

See the documentation 请参阅文档

class YourClass<T> 
{
    public YourClass(T value){}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM