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
integer
boolean
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.
object
string
3 Answers
3
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 type1,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.
1Especially because, as vc74 points out in a comment, overload resolution (generally, ignoring dynamic
) is done at compile time based on compile-time types3.
dynamic
2And this fits the same broad principal for overloads. 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)
3I 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.
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)
You could use a generic class.
See the documentation
class YourClass<T>
{
public YourClass(T value){}
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Depends, what you are trying to achieve?
– kuskmen
5 hours ago