Overloaded methods tend to encourage a habit of duplicating the code between all methods of the method group. For example, I may concat a string, write it to file, etc in one method but then do the same in another method but with the addition of an additional parameter (Creating the overload).
The methods themselves could go in a base class which will make the concrete class look cleaner but the base class will have the problem then (working around the problem). The params keyword seems like a solution but I can imagine if I really think this idea through (using params rather than individual parameters), there'll be some sort of other issue.
Am I therefore the only one to think that overloads promote code duplication?
Thanks
Usually I'd have the actual implementation in the overload with the most parameters, and have the other overloads call this one passing defaults for the parameters which aren't set.
I certainly wouldn't be duplicating code which writes to a file across different overloads - in fact, that code alone could probably be refactored out into its own properly parameterized private method.
In addition to the options above, upcoming in the new version of c# is default parameter capabilities, which is basically just syntatic sugar for what Winston suggested.
public string WriteToFile(string file, bool overWrite = false){
}
A common pattern that more or less eliminates this problem is to have one base implementation, and have each overload call the base implementation, like so:
string WriteToFile(string fileName, bool overwrite) {
// implementation
}
string WriteToFile(string fileName) {
WriteToFile(fileName, false);
}
This way there is only one implementation.
If all of the overloads use the same code, they just handle it slightly differently, perhaps you should either make another function that each overload calls, or if one of them is a base, generic version, then each of the other overloads should call the generic one.
Related
I have a function that I would like to overload to take the same data in a different form, that is:
void encode(byte[,,],float)
and
void encode(Bitmap[],float)
I have written one overload of the function, and it is quite long(about 60 lines).
My question is, when writing the second overload, should I copy most of the code of the first overload and make little changes, or should I convert the data and call the first overload?
Never copy your code from a method to another one, It is a big mistake. For overloading you should make a method with most parameters and for other overloads call the one that has most parameters with some default values.
If at all possible, avoid large repetitions.
One overload calling another, as you suggest, is often a good approach.
It can also often work well to factor out the commonality into a private method that both overloads call. This private method could be generic if necessary to allow for similar operations on different types.
There are though times when repetition is inevitable, particularly when overloading on the primitive types. Even here though see if you can factor out at least some of the functionality, or consider T4 templates.
When I first learned about extension methods I read this:
In general, we recommend that you implement extension methods
sparingly and only when you have to. Whenever possible, client code
that must extend an existing type should do so by creating a new type
derived from the existing type.
However, I have numerious times seen a very liberal use of extension methods in various production code bases.
Granted, my experience is not representative of the majority but I would like to know if there's a shift in the guidelines, an alternate design philosophy, or if I just happened to see enough code that ignored the guidlines to make me think so?
NOTE: I am not trying to spark a debate (which will promptly lead to this question closing) - I've honestly been wondering about this for a while and feel my best chance at getting an answer is here on SO.
I think all this highlights is the usual difference between theory and practice. In theory we should use them sparingly but in practice we don't. In theory we should do a lot of things that we don't in practice do, in life in general, not only programming.
Polymorphism does not work with extension methods as they are bound in compile time.
ParentClass parentClass = new ParentClass();
ParentClass derivedClass = new DerivedClass();
If both of these classes have an extention method called ExtensionMethod() (I have defintely seen extension methods attempting to mimick virtual/overriden methods), both of these calls would call the parent class's extension method:
parentClass.ExtensionMethod();
derivedClass.ExtensionMethod();
In order to actually use the derived extension method, you would have to call:
((DerivedClass)derivedClass).ExtensionMethod();
Extending class is good approach, but often it is not available for code that uses third party libraries (which is common case for production code unlike in education/sample code). So derive new class if it makes sense, but feel free to use extension methods when they make code more readable.
There are multiple reasons why there are a lot of extension methods:
often you can't extend a class to add methods that would make your product code to be more readable. I.e. value types like String or some base classes in hierarchies like Stream.
extension methods is valuable way to add methods to interfaces without polluting the interface. LINQ is good example how it produces more readable code.
some frameworks recommend to use extension methods in particular cases. I.e. for MVC it is recommended to add extensions to HtmlHelper.
I think that there is pros and cons about using the extension methods.
Pros: The extension methods could be regarded as the visitor pattern(GoF). So, it takes advantage of the pattern, which is, without modifying code, we can extend some features.
Cons: Despite the advantage , why the MSDN tells using the extension methods sparingly is that, IMO, the extension methods would cause problem at some point. First, if the object for extension methods has different namespace from the extension, we should know where it is. It causes that sometimes we cannot use some important features from the extension. Moreover, I saw lot of code with extension abuse. Since extension is based on Type, sometime an object of that Type really do not need the extension, but when coding, we should see lots of extension method.
[update]
IMO, abuse about the extension methods
using so general type for extension method, like object: if there is lots of extension methods with object type and that extension is only focused on few types, it'll annoy us, as every object is linked with the methods.
broken linking with dot operator or misconception: Let me show an example. There is the code like below and we should call the Read and then Write method in order. However, we can call the methods in opposite order.
public static string Read(this string message)
{
//do something
return message;
}
public static string Write(this string message)
{
//do something
return message;
}
public static void Method()
{
"message".Read().Write();
"message".Write().Read(); // this is problem!
}
I have a feeling this question is a can of worms but I am going to ask anyway... :)
I have a method:
private MembershipUser GetUserFromReader(SqlDataReader reader)
And I want overload this method with a different return type:
private User GetUserFromReader(SqlDataReader reader)
But the compiler complains that the two methods have the same signature.
So, what is the best way to do this? I would prefer to not add an unnecessary
parameter just to change the method signature.
I have played with the idea of doing something like:
private User GetUserFromReader(T reader)
But haven't really explored this in full yet. It seems like I'll need to make a
bunch of changes with how I use my reader object.
Any ideas? What is the best practice when you have two overloaded
methods of the same signature?
Thanks for helping out...
Why overload it? Why not just let the method say what it does, like so:
private MembershipUser GetMembershipUserFromReader(SqlDataReader reader)
private User GetUserFromReader(SqlDataReader reader)
If you really want to differentiate the return type, but use the same method signature, you could use generics:
private T GetUserFromReader<T>(SqlDataReader reader)
But it's much simpler to just rename the methods, as in Luhmann's answer.
Your only real options are:
Change the name of the function
Change the signature of the function
I hate to be trite, but there isn't a way around the restriction on differentiating methods solely by return type.
If one of the overloads is declared in a parent class then you can use the new keyword to "hide" the higher method from callers, but new (on a member declaration) is usually considered evil.
You can't change the return type on an overload. How is the compiler supposed to tell which one you want to use?
What you should do is return a common superclass of everything you might want to return, and then just return whatever is applicable.
Either that, or name the methods differently, since they clearly do different things.
The simple answer is that, as far as C# is concerned, you can't. Overloading by return type is permitted (I think) by MSIL, but not by C#.
The only real choice (i.e, excluding adding a "dummy" parameter), is to call one method GetMembershipUserFromReader and the other GetUserFromReader
What is the general thinking on the use of extension methods that serve no purpose other than enhancing readability?
Without using extension methods we might have the method
IEnumerable<DependencyObject> GetDescendents(DependencyObject root) {}
that could be called with
var descendents = GetDescendents(someControl);
or
foreach (var descendent in GetDescendents(someControl)) {}
Although there's nothing wrong with this I find the instance.method() notation to be more readable so I might consider making this an extension method with this signature
public IEnumerable<DependencyObject> GetDescendents(this DependencyObject root) {}
allowing it to be called with
var descendents = someControl.GetDescendents();
or
foreach (var descendent in someControl.GetDescendents()) {}
So my question is whether you think this is reasonable or an abuse of extension methods. If it was simply a matter of declaring the function differently I wouldn't hesitate; but the fact that using an extension method requires it be coded in a different, static class makes me wonder if it's worth the effort or not. The example I'm using above is a fairly generic one and might have merit as an extension method that will be used in several places but often this is not the case and I would be coding the static class containing the extension in the same file as the single class that uses it.
I think the big advantage of extension methods is discoverability. If someone is unaware that one of their team members created a GetDescendents method in a utility class somewhere, they'll never use it. However, if that method starts to show up in Intellisense or in the Object Browser, there's a decent chance they will stumble across it. If you start to make more extensive use of extension methods, people will start to use the tools I mentioned to look for extensions that add value.
Most if not all extension methods fall into this category to some degree, since they can't operate on the internals of a class anymore than your static function. At any rate, any extension method can be rewritten in a static class with an extra parameter representing the object (arguably, that's exactly what an extension method is anyway).
To me, it's entirely a question of style: in the example you provided, I'd probably jump for the extension method. I think the important question here is, Is this function something I'd write as part of the class if I were to reimplement the class, and does it make sense as such? If yes, then go for it, if no, then consider a different solution.
An extension method only exists to improve readability - it is merely a syntax shortcut that allows you, by specifying the this keyword on the first argument, allows you to call the method on the object instance in question. So I think it is entirely reasonable.
Recently I asked a question about how to clean up what I considered ugly code. One recommendation was to create an Extension Method that would perform the desired function and return back what I wanted. My first thought was 'Great! How cool are Extensions...' but after a little more thinking I am starting to have second thoughts about using Extensions...
My main concern is that it seems like Extensions are a custom 'shortcut' that can make it hard for other developers to follow. I understand using an Extension can help make the code syntax easier to read, but what about following the voice behind the curtain?
Take for example my previous questions code snippet:
if (entry.Properties["something"].Value != null)
attribs.something = entry.Properties["something"].Value.ToString();
Now replace it with an Extension:
public static class ObjectExtensions
{
public static string NullSafeToString(this object obj)
{
return obj != null ? obj.ToString() : String.Empty;
}
}
and call using the syntax:
attribs.something = entry.Properties["something"].Value.NullSafeToString();
Definetely a handy way to go, but is it really worth the overhead of another class object? And what happens if someone wants to reuse my code snippet but doesn't understand Extension? I could have just as easily used the syntax with the same result:
attribs.something = (entry.Properties["something"].Value ?? string.Empty).ToString()
So I did a little digging and found a couple of articles that talked about the pros/cons of using Extensions. For those inclined have a look at the following links:
MSDN: Extension Methods
Extension Methods Best Practice
Extension Methods
I can't really decide which is the better way to go. Custom Extensions that do what I want them to do or more displayed code to accomplish the same task? I would be really interested in learning what 'real' developers think about this topic...
Personally I think the "problems" of extension method readability are vastly overstated. If you concentrate on making your code easy to read in terms of what it's doing, that's more important most of the time than how it's doing it. If the developer wants to trace through and find out what's actually happening behind the scenes, they can always click through to the implementation.
My main problem with extension methods is their discovery method - i.e. via a specified namespace instead of a specified class. That's a different matter though :)
I'm not suggesting that you put in extension methods arbitrarily, but I would seriously consider how often you need to know how every expression in a method works vs skimming through it to see what it does in broader terms.
EDIT: Your use of terminology may be misleading you slightly. There's no such thing as an "extension object" - there are only "extension methods" and they have to exist in static types. So you may need to introduce a new type but you're not creating any more objects.
[OP] Definetely a handy way to go, but is it really worth the overhead of another class object?
No extra class object is created in this scenario. Under the hood, extension methods are called no differently than a static method. There is an extra metadata entry for the extension method container but that is pretty minimal.
[OP] And what happens if someone wants to reuse my code snippet but doesn't understand Extension Objects?
Then it would be a good time to educate them :). Yes, there is the risk that a new developer may not be comfortable with extension methods to start. But this is hardly an isolated feature. It's being used more and more in all of the code samples I'm seeing internally and on the web. It's something that is definitely worth while for a developer to learn. I don't think it fits into the category of "to esoteric to expect people to know"
The only serious weirdness to deal with in Extension methods are:
They do not have to cause a null reference exception if the left hand side (the object on which it appears you are invoking a method) is null.
can sometimes be useful, but is contrary to expectations as such should be used with extreme caution.
They are not accessible through reflection on the classes/interfaces to which they apply.
generally not a problem, but worth keeping in mind.
Name collisions with other extension methods involve a lengthy resolution rule sequence
if you care the sequence is to prefer:
Extension methods defined inside the current module.
Extension methods defined inside data types in the current namespace or any one of its parents, with child namespaces having higher precedence than parent namespaces.
Extension methods defined inside any type imports in the current file.
Extension methods defined inside any namespace imports in the current file.
Extension methods defined inside any project-level type imports.
Extension methods defined inside any project-level namespace imports.
[OP] And what happens if someone wants to reuse my code snippet but doesn't understand Extension Objects?
The extension methods will not show in the intellisense for the object if the assembly that implements them is not references in the project. Your code snippet will also not compile. That could potentially create a bit of a confusion to the other developer.
If the extension method assembly is referenced, it will show in the intellisense, but it will be not mentioned in the documentation for the object. This could potentially cause a bit of confusion as well.
However, as #JaredPar mentioned, the extension methods as a technique are used more and more and I would expect most of the C# programmers to know about them. Thus, I wound't be too worried about any potential confusion.
C# Extensions is an additional "tool" provided by .Net in order to help you write your code a little bit nicer. Another advantage of them is, that they handle null. Although they seem very usable, I try to use them only in certain cases that will really tidy up my code, because they are not standard coding methods and they stand a little bit seperate from other classes as they have to be in static classes and are static themselves.
Let's say their implementation is a little bit untidy, but their use is made tidier.
It is also important to mention that they only exist in C# and VB.Net (Java doesn't have Extensions). Another important fact is that Extensions have no priority over standard methods, meaning that if a method is implemented in a class with the same name as an extension method on the same class, then the first method is the one that will be called and not the extension method.
Below there are three cases where I often use them, why I use them and alternative solutions that would solve the same problem:
1. To implement specific methods for generic classes:
I have a generic type, let's say a collection List<T>. I want to do a method that applies only to a specific kind of list. Let's say a method that creates a union from a list of strings using a seperator
("A", "B", "C", " sep " --> "A sep B sep C"):
public static string union(this List<string> stringList, String seperator)
{
String unionString = "";
foreach (string stringItem in stringList) {
unionString += seperator + stringItem; }
if (unionString != "") {
unionString = unionString.Substring(seperator.Length); }
return unionString;
}
In case I didn't want to use an extension, I would have to create a new class "StringCollection : List<string>" and implement my method there. This is mainly not a problem and it is actually better in most cases, but not in all cases. If for example you are receiving all your data in lists of strings in many cases, you don't have to convert those lists in StringCollections each time you want to use union, but use an extension instead.
2. To implement methods that need to handle null:
I need a method to convert an object to a string without throwing an exception in case the object is null
public static String toStringNullAllowed(this Object inputObject)
{
if (inputObject == null) { return null; }
return inputObject.ToString();
}
In case I didn't want to use an extension, I would have to create a class (probably static), for example StringConverter, which will do the same job, with more words than a simple myObject.toStringNullAllowed();
3. To extend value types or sealed classes:
Value types such as int, float, string, etc as well as sealed classes (classes that cannot be inherited) cannot be extended through inheritance. Below you can see an example of extending integers to be able to be converted to x-digit Strings (for example integer 34, digits 5 --> "00034"):
public static String toXDigit(this int inputInteger, int x)
{
String xDigitNumber = inputInteger.ToString();
while (xDigitNumber.Length < x) { xDigitNumber = "0" + xDigitNumber; }
return xDigitNumber;
}
Again an alternative solution would be a static class (like a toolbox), let's say "Math".
In that case you would write: Math.toXDigit(a, x);
While with the extension method: a.toXDigit(x);
The extension method looks better and is more understandable, like speaking English
To conclude, I guess the disadvantage of extensions is that their implementation is seperated from standard classes and looks a little bit odd or difficult to programmers that are not used to them, while their advantage is that they offer a more understandable, tidier and encapsulated use of the language.