Overloaded methods in interface - c#

my question for today: are overloaded methods in interface bad? You know, the "omit parameters if you don't care, we'll figure out the default values" kind of overloaded methods.
Like that:
void Add(object item);
void Add(object item, bool shouldDoSomething);
void Add(object item, bool shouldDoSomething, IUltraObscureDeviceContext context);
In this case I tend to think that only the latter belongs to an interface and others should be implemented in abstract class on top of it. But then again, I'm not sure.
Also, there are times when you just want different overloads doing slightly different work (stop me right there if overloaded methods should never be used for that). Or sometimes you can't just stuff nulls in place of some parameter, you want the exception thrown if something is null. Should I not use overloading in this case?
So basically I'm looking for some guidelines on overloaded methods in interfaces vs overloaded methods in abstract classes implementing these interfaces and so on.
Thanks in advance

If the defaults depend on the receiver of the method call, declare them as interface methods.
If the defaults are just defaults irrespective of the receiver, create the various reduced-argument-list overloads as extension methods and save implementors the headache of having to supply all the overloads themselves.
If you're dealing with some sort of nitty-gritty 80/20 rule exceptions, where implementation-independent defaults are almost but not quite always sufficient, you have a few options, none of which are that good:
Deal with it as if they're always different, declare them as interface methods, and reimplement them everywhere. Not very DRY.
Deal with it as if they're always different, declare them as interface methods, and inherit a base class that provides the 80% default implementation. Kind of clumsy, and not good if your sole base-class slot is already occupied.
Create another interface containing those specific methods. Declare extension methods with matching signature against the original interface. In the extension methods, as-cast the this argument to the new interface type, and if it matches, call it there, otherwise fill in stock defaults. Very funky, reliant on dynamic casting so not that great in an inner loop, but it decouples the defaults from both implementor and caller without sacrificing flexibility for implementors that can't take the "default defaults".

Overloaded methods in an interface maybe Ok if the design of the interface warrants it. I've personally never needed to do this.
I wouldn't define default parameters values in an interface. That is an implementation detail that implementing classes that choose to surface.
you comment about having different implementations for the overloads....
Don't do that. Think of implementation of these overloaded methods as calling the one method that has all of the parameters defined with some default values. That's how users of your code would expect things to be.
If you need different behavior then use polymorphism. That's what its there for.

IMO if the interface/contract spells it out, there should be no problem. However the goal is to simplify things when exposing an interface and hide the details. And thats where optional params come in handy.Pefectly object oriented languages like Python do not even have overloading AFAIK

Related

interface inheriting multiple interfaces: how is this handled by a C# compiler?

Recently I found out that C# allows for
An interface can inherit from one or more base interfaces.
For instance, the IScreen in Caliburn.Micro does this in http://caliburnmicro.codeplex.com/SourceControl/latest#src/Caliburn.Micro/IScreen.cs
namespace Caliburn.Micro
{
public interface IScreen : IHaveDisplayName, IActivate, IDeactivate,
IGuardClose, INotifyPropertyChangedEx
{
}
}
I get why this is useful, as it implies that a class implementing IScreen also needs to implement the other interfaces.
But I wonder how the C# handles that compiler and run-time wise.
A little background/context of this question:
I come from a background where interfaces define a method-table, and that classes implementing interfaces have both their own method table, and pointers to the method tables of the interfaces they implement.
Sub questions swirling my mind stem from various multiple class inheritance discussions I had with people in the past, of which I think they apply to this case as well:
Having an interface be able to inherit from multiple base interfaces, how would the order of methods in that table be?
What if those interfaces have common ancestors: would those methods appear multiple times in the table?
What if those interfaces have different ancestors, but similar method names?
(I'm using the word methods here, implying that a property defined in an interface will have a get_ or set_ method).
Any insight into this is much appreciated, as well as tips on how to phrase this question better.
First of all, let's be explicit in saying that "interface inheritance" is not quite the same thing as class-based inheritance (and using the word "inheritance" for both is perhaps misleading).
That's because interfaces cannot be instantiated on their own, so the compiler/runtime pair does not have to keep track of how to make a virtual call for standalone interface types (e.g. you don't need to know how to call IEnumerable.GetEnumerator -- you just need to know how to call it on a specific type of object). That allows for handling things differently at compile time.
Now I don't actually know how the compiler implements "interface inheritance", but here's how it could be doing it:
Having an interface be able to inherit from multiple base interfaces,
how would the order of methods in that table be?
It's not necessary for the "derived" interface to have a method table that includes the methods from all of its ancestor interfaces because it does not actually implement any of them. It's enough for each interface type to only have a table of methods it defines itself.
What if those interfaces have common ancestors: would those methods
appear multiple times in the table?
Given the answer to the previous question, no. In the end a concrete type will only implement IFoo just once, regardless of how many times IFoo appears in the "hierarchy" of implemented interfaces. Methods defined in IFoo will only appear in IFoo's bookkeeping tables.
What if those interfaces have different ancestors, but similar method
names?
Again, no problem. You need appropriate syntax to tell the compiler "here's how to implement IFoo.Frob and here's IBar.Frob", but since methods of IFoo and IBar will be mapped in separate tables there are no technical issues.
Of course this leaves the question "how are methods dispatched at runtime?" unanswered. But it's not that difficult to imagine a possible solution: each concrete type C has pointers to one method table per interface it implements. When it's time to make a virtual method call the runtime looks at the concrete type, finds the table for the interface whose method is going to be called (the type of the interface is known statically) and makes the call.
I am unable to speak to how the official CLR does it.. but the Rotor distribution aggresively overlays common interface ancestors on top of one another in an objects vtable. It also allocates extra SLOTs into the concrete objects vtable where appropriate thereby reducing the need to jump from concrete type to interface vtable and then to the implementation.. the method offset is calculated at JIT time. If this optimization cannot be performed, then a single method can occupy the vtable more than once.
So the answer is (in regards to Rotor anyway), that it really is an implementation detail and any overlaying/optimizations etc are left completely up to what the compiler decides is best at the time it compiles the type.

Class and extension method container class in same namespace. What is the benefit?

I was trying NBuilder in my unit test. An excellent library. However, I could not explain the following structure of classes and interfaces.
In FizzWare.NBuilder namespace:
ISingleObjectBuilder
SingleObjectBuilderExtensions
In FizzWare.NBuilder.Implementation
IObjectBuilder`
ObjectBuilder
SingleObjectBuilderExtensions is simply a wrapper on IObjectBuilder.
The client code should usually use a class named Builder which has a static method that gives you ISingleObjectBuilder. You never need to instantiate any of the classes in client code.
Now, I dont get the point of the SingleObjectBuilderExtensions. Does it give any kind of design benefit? Why not the methods are directly in ISingleObjectBuilder specially when the two interfaces are in same namespace.
ISingleObjectBuilder is an interface; interfaces cannot provide implementation. That would mean that every implementation of ISingleObjectBuilder would need to provide the implementation.
However, in many cases, a method has a pre-defined behaviour, and just needs access to other members of the interface (i.e. just members of ISingleObjectBuilder), so there is no benefit in making each implementation provide this.
Additionally, it is not a good idea to add more members to an existing interface, since that would be a breaking change for all existing implementations.
Extension methods solve both of these issues:
the extension method will work for all implementations of ISingleObjectBuilder
it doesn't change the existing API, so all existing implementations will continue to be valid
Having it in the same namespace simply makes it convenient. It is a likely bet that any code using ISingleObjectBuilder already has a using directive importing that namespace; therefore, most code will already see the extension method in the IDE simply by pressing . in the IDE.
To add a concrete example, LINQ-to-Objects works on IEnumerable<T>. There are lots of IEnumerable<T> implementations. If each of them had to write their own First(...), FirstOrDefault(...), Any(...), Select(...) etc methods, that would be a huge burden - bot would provide no benefit as the implementations would be pretty much identical in most cases. Additionally, fitting this onto the interface retrospectively would have been disastrous.
As a side note: per-type versions of a method always take precedence over extension methods, so if (in the case of LINQ-to-Objects) you have a type that implements IEnumerable<T> (for some T), and that type has a .First() instance method, then:
YourType foo = ...
var first = foo.First();
will use your version, not the extension methods.
Extension methods are only syntactic sugar. They are normal static methods that work with public data the class they "extend" exposes.
There doesn't seem to be need for those extension methods to work with private fields and it also gives you ability to have interface instead of abstract class. And everyone knows interfaces are better choice than abstract classes.
And the reason for both to be in same namespace is to avoid declaring new namespace just to use the extension methods. How many times did it happen to you, that you tried to use LINQ only to notice there are no methods in intellisense or the code didn't compile. Reason being there was not System.Linq namespace included.

"Program to an interface" using extension methods: When does it go too far?

Background: In the spirit of "program to an interface, not an implementation" and Haskell type classes, and as a coding experiment, I am thinking about what it would mean to create an API that is principally founded on the combination of interfaces and extension methods. I have two guidelines in mind:
Avoid class inheritance whenever possible. Interfaces should be implemented as sealed classes.
(This is for two reasons: First, because subclassing raises some nasty questions about how to specify and enforce the base class' contract in its derived classes. Second, and that's the Haskell type class influence, polymorphism doesn't require subclassing.)
Avoid instance methods wherever possible. If it can be done with extension methods, these are preferred.
(This is intended to help keep the interfaces compact: Everything that can be done through a combination of other instance methods becomes an extension method. What remains in the interface is core functionality, and notably state-changing methods.)
Problem: I am having problems with the second guideline. Consider this:
interface IApple { }
static void Eat(this IApple apple)
{
Console.WriteLine("Yummy, that was good!");
}
interface IRottenApple : IApple { }
static void Eat(this IRottenApple apple)
{
Console.WriteLine("Eat it yourself, you disgusting human, you!");
}
sealed class RottenApple : IRottenApple { }
IApple apple = new RottenApple();
// API user might expect virtual dispatch to happen (as usual) when 'Eat' is called:
apple.Eat(); // ==> "Yummy, that was good!"
Obviously, for the expected outcome ("Eat it yourself…"), Eat ought to be a regular instance method.
Question: What would be a refined / more accurate guideline about the use of extension methods vs. (virtual) instance methods? When does the use of extension methods for "programming to an interface" go too far? In what cases are instance methods actually required?
I don't know if there is any clear, general rule, so I am not expecting a perfect, universal answer. Any well-argued improvements to guideline (2) above are appreciated.
Your guideline is good enough as it is: it already says "wherever possible". So the task is really to spell out the "wherever possible" bit in some more details.
I use this simple dichotomy: if the purpose of adding a method is to hide the differences among subclasses, use an extension method; if the purpose is to highlight the differences, use a virtual method.
Your Eat method is an example of a method that introduce a difference among subclasses: the process of eating (or not) an apple depends on what kind of apple it is. Therefore, you should implement it as an instance method.
An example of a method that tries to hide the differences would be ThrowAway:
public static void ThrowAway(this IApple apple) {
var theBin = RecycleBins.FindCompostBin();
if (theBin != null) {
theBin.Accept(apple);
return;
}
apple.CutUp();
RecycleBins.FindGarbage().Accept(apple);
}
If the process of throwing away an apple is the same regardless of the kind of the apple, the operation is a prime candidate for being implemented in an extension method.
For me the expected output was correct. You type-casted (probably using that wrong) the variable to as an IApple.
For example:
IApple apple = new RottenApple();
apple.Eat(); // "Yummy, that was good!"
IRottenApple apple2 = new RottenApple();
apple2.Eat(); // "Eat it yourself, you disgusting human, you!"
var apple3 = new RottenApple();
apple.Eat(); // "Eat it yourself, you disgusting human, you!"
Question: What would be a refined / more accurate guideline about the use of extension methods vs. (virtual) instance methods? When does the use of extension methods for "programming to an interface" go to far? In what cases are instance methods actually required?
Just my personal opinion when developing application:
I use instance methods when I'm writing something that I may or someone else may consume. This is because it is a requirement for what the type actually is. Consider an interface/class FlyingObject with a method Fly(). That is a basic fundamental method of a flying object. Creating an extension method really doesn't make sense.
I use (a lot) of Extension methods, but these are never a requirement for the use of the class they extend. For example, I have extension method on int that creates a SqlParameter (additionally it is internal). Still it makes no sense to have that method as part of the base class of int, it really has nothing to do with what an int is or does. The extension method is visually nice way of creating a reusable method that consumes a class/struct.

When is it correct to create an extension method?

I have a piece of code like the following:
public class ActivityHelper
{
public void SetDate(IList<Activity> anActivityList)
{
foreach(Activity current in anActivityList)
{
current.Date = DateTime.Now;
}
}
//More methods, properties, fields, etc...
}
This could easily be converted to an extension method. For example:
public static void SetDate(this IList<Activity> aList)
{
foreach(Activity current in anActivityList)
{
current.Date = DateTime.Now;
}
}
The original function doesn't use any instance specific data or methods from the ActivityHelper class which makes it seem like it is in the incorrect place. Is this the correct time to write an extension method? What are the correct scenarios in which to create extension methods?
Brad Adams has written about extension method design guidelines:
CONSIDER using extension methods in any of the following scenarios:
To provide helper functionality relevant to every implementation of an interface, if said functionality can be written in terms of the core interface. This is because concrete implementations cannot otherwise be assigned to interfaces. For example, the LINQ to Objects operators are implemented as extension methods for all IEnumerable types. Thus, any IEnumerable<> implementation is automatically LINQ-enabled.
When an instance method would introduce a dependency on some type, but such a dependency would break dependency management rules. For example, a dependency from String to System.Uri is probably not desirable, and so String.ToUri() instance method returning System.Uri would be the wrong design from a dependency management perspective. A static extension method Uri.ToUri(this string str) returning System.Uri would be a much better design.
I think Extension methods are only appropriate if there is a compelling reason to make the method an extension method.
If the type is one you do not control, and the method should appear to be integral to the type, or if there is a compelling reason to not put the method directly on the type (such as creating an unwanted dependency) then an extension method could be appropriate.
Personally, if the expectation of the user of your API will already be to use the "ActivityHelper" class when working with collections of Activities, then I would probably not create an extension method for this. A standard, non-extension method will actually be a simpler API, since it's easily understood and discoverable. Extension methods are tricky from a usage standpoint - you're calling a method that "looks like" it exists somewhere other than where it actually exists. While this can simplify syntax, it reduces maintainability and discoverability.
In my experience extension methods work best when they:
Don't have side-effects (most of the extension methods my team wrote that have side-effects, we ended up removing because they caused more problems than they helped)
Offer functionality that applies to every possible instance or value of the type they're extending. (Again citing an example from my team, string.NormalizeUrl() is not appropriate because not all strings are even URLs anyway)
Well i usually create extension methods to help me write codes which have a smooth flow. Its generally depends upon the method you are creating.
If you feel that the method should have already been in framework and is too general then its okay to create an extension method for that.
But you need to first analyze that the class you are extending will always will be in state that your extension method can handle.
For Guidelines here to Brad's Article
http://blogs.msdn.com/b/brada/archive/2009/01/12/framework-design-guidelines-extension-methods.aspx
In essence, Extension Methods provide a more fluent style syntax for Helper methods. This translates into the ability to seemingly add functionality to types or all implementations of interfaces.
However, I generally steer away from declaring Extension Methods with a void returntype, as I feel the usefulness of this fluent style syntax, which allows you to compose statements, is negated when the method in question doesn't return anything.
However, I guess it can be handy to have your methods picked up by IntelliSense... :-)

C#: Specify that a function arg must inherit from one class, and implement an interface?

I'm making a game where each Actor is represented by a GameObjectController. Game Objects that can partake in combat implement ICombatant. How can I specify that arguments to a combat function must inherit from GameObjectController and implement ICombatant? Or does this indicate that my code is structured poorly?
public void ComputeAttackUpdate(ICombatant attacker, AttackType attackType, ICombatant victim)
In the above code, I want attacker and victim to inherit from GameObjectController and implement ICombatant. Is this syntactically possible?
I'd say it probably indicates you could restructure somehow, like, have a base Combatant class that attacker and victim inherit from, which inherits from GameObjectController and implements ICombatant.
however, you could do something like
ComputeAttackUpdate<T,U>(T attacker, AttackType attackType, U victim)
where T: ICombatant, GameObjectController
where U: ICombatant, GameObjectController
Although I probably wouldn't.
Presumably all ICombatants must also be GameObjectControllers? If so, you might want to make a new interface IGameObjectController and then declare:
interface IGameObjectController
{
// Interface here.
}
interface ICombatant : IGameObjectController
{
// Interface for combat stuff here.
}
class GameObjectController : IGameObjectController
{
// Implementation here.
}
class FooActor : GameObjectController, ICombatant
{
// Implementation for fighting here.
}
It is only syntactically possible if GameObjectController itself implements ICombatant; otherwise, I would say you have a design problem.
Interfaces are intended to define the operations available on some object; base classes identify what that object is. You can only pick one or the other. If accepting the ICombatant interface as an argument is not sufficient, it might indicate that ICombatant is defined too narrowly (i.e. doesn't support everything you need it to do).
I'd have to see the specifics of what you're trying to do with this object in order to go into much more depth.
What if you did this instead:
public class GameObjectControllerCombatant : GameObjectController, ICombatant
{
// ...
}
Then derive your combatant classes from this instead of directly from GameObjectController. It still feels to me like it's breaking encapsulation, and the awkwardness of the name is a strong indication that your combatant classes are violating the Single Responsibility Principle... but it would work.
Well, sort of. You can write a generic method:
public void ComputeAttackUpdate<T>(T attacker, AttackType type, T victim)
where T : GameObjectController, ICombatant
That means T has to satisfy both the constraints you need. It's pretty grim though - and if the attacker and victim could be different (somewhat unrelated) types, you'd have to make it generic in two type parameters instead.
However, I would personally try to go for a more natural solution. This isn't a situation I find myself in, certainly. If you need to regard an argument in two different ways, perhaps you actually want two different methods?
If you control all the classes in question, and if GameObjectController doesn't define any fields, the cleanest approach would be to define an IGameObjectController (whose properties and methods match those of GameObjectController) and an ICombatantGameObjectContoller (which derives from both IGameObjectController and ICombatant). Every class which is to be usable in situations that require both interfaces must be explicitly declared as implementing ICombatantGameObjectController, even though adding that declaration wouldn't require adding any extra code. If one does that, one can use parameters, fields, and variables of type ICombatantGameObjectController without difficulty.
If you can't set up your classes and interfaces as described above, the approach offered by Jon Skeet is a generally good one, but with a nasty caveat: to call a generic function like Mr. Skeet's ComputeAttackUpdate, the compiler has to be able to determine a single type which it knows is compatible with the type of the object being passed in and with all of the constraints. If there are descendants of GameObjectController which implement ICombatant but do not derive from a common base type which also implements GameObjectController, it may be difficult to store such objects in a field and later pass them to generic routines. There is a way, and if you need to I can explain it, but it's a bit tricky.

Categories

Resources