There could be just one implementation for IBaseAction.CanSave() So I think you can't do this conceptually.
There could be just one implementation for IBaseAction.CanSave(). So I think you can't do this conceptually.
Thanks for pointing out my mistake. Since these interfaces are semantic aspects of my base action I'll just have to leave the option to explicitly redefine my interface methods where ever I need – TDaver Jun 19 at 22:08.
You can't do what you describe. Just imagine what would happen if a client requests the IBaseAction interface. Which one should be returned?
It sounds to me like each action should be implemented by separate objects.
I cannot do the separate implementation, but you're right that I cannot do exactly what I described. – TDaver Jun 19 at 22:06 I don't see how you can do it without separate objects but I don't know your full problem – David Heffernan Jun 19 at 22:08.
You're trying to implement diamond inheritance with Interfaces. The whole reason you're not allowed to implement multiple classes in the first place is to avoid diamond inheritance. If you want to combine two interfaces together as a ComplexAction, you'd do something like the following: interface IAct { bool CanAct(); } class Act1 : IAct { public bool CanAct() { return true; } } class Act2 : IAct { public bool CanAct() { return false; } } class ComplexAction : IAct { private Act1 action1; private Act2 action2; public ComplexAction(Act1 action1, Act2 action2) { this.
Action1 = action1; this. Action2 = action2; } public bool CanAct() { return action1.CanAct() && action2.CanAct(); } } A ComplexAction is a composition of different IActs. If you're appending a number to an Interface name, chances are high that you're doing something wrong.
If instead, you want to define different behaviour based on the Interface, that Interface must have it's method defined on itself. Interface IAct1 { bool CanAct(); } interface IAct2 { bool CanAct(); } class SometimesAct1SometimesAct2 : IAct, IAct1, IAct2 { bool IAct1.CanAct() { return false; } bool IAct2.CanAct() { return true; } public bool CanAct() { Console. WriteLine("Called on IAct or SometimesAct1SometimesAct2"); return false; } } To avoid the problems of diamond inheritance, you must give an implementation for ALL interfaces that define a particular method, so there is no ambiguity.
1, the first code is good to know, didn't think of it myself, however the second one is closer to what I want! – TDaver Jun 19 at 22:17.
I think you're trying to use inheritance for something it was not meant to do. If you have a complex action, it's composed of simpler actions, it's not multiple different actions at the same time. Your ComplexAction should have properties Action1 and Action2, of types IAction1 and IAction2 that have properly implemented CanSave().
It's not defined by IAction1 but by IBaseAction. The solution is to not let complex action implement both (your current solution might be breaking SRP).
You do need to re-declare the members of IBaseAction on the interfaces that need to defer, but then you also need to implement IBaseAction's members implicitly or explicitly if there are no implicit implementations of the members (to make sure all interfaces are satisfied). Interface IBase { void Act(); } interface IAction1 : IBase { void Act(); } interface IAction2 : IBase { void Act(); } class MyClass : IAction1, IAction2 { public void Act() { Console. WriteLine( "satisfies IBase.Act()" ); } void IAction1.Act() { Console.
WriteLine( "IAction1.Act()" ); } void IAction2.Act() { Console. WriteLine( "IAction2.Act()" ); } static void Main( string args ) { MyClass cls = new MyClass(); cls.Act(); IAction1 a = cls; a.Act(); IAction2 be = cls; b.Act(); Console.ReadKey(); } } It may be redundant to point out that this design is strange to have overlapping-named members that force you into jumping through hoops like this, but I figured I'd note it anyway. You did say you can't toss your current hierarchy, but it might be possible to refactor it to avoid these shenanigans.
– Avada Kedavra Jun 19 at 22:08 +1 for taking the time to write code. My real solution is similiar, just that I won't explicitly implement EVERY method, only those I want to differ from my base implementation (in this case IAction1, as IAction2,3,4,5.... has to be implemented the same way (the default)) – TDaver Jun 19 at 22:09 @Avada: Probably because it's ugly to continue down the path of that design, considering he's got multiple members on multiple interfaces to explicitly implement.It's just hard to maintain multiple implementations like that. – Joel B Fant Jun 19 at 22:10 1 @TDaver: Good thing you could simplify it like that.
You'd only have to re-declare IBaseAction's members on IAction1 in that case, as the others would be implemented as IBaseAction's members. – Joel B Fant Jun 19 at 22:12 1 Surely, but the wierdness in the design is as well outlined in your answer. Thus I see no reason for downvoting.
Well well, order restored by TDaver :) – Avada Kedavra Jun 19 at 22:12.
This won't work. You are assuming that IAction1 inherits IBaseAction, but that is not the case. Interfaces cannot inherit other interfaces.
You can check this out by using reflection to see the baseclass of IAction1. It will not be IActionBase. What you are saying with your code is: when a class implements IAction1 then it is also required to implement IBaseAction.
C# will then help you by assuming you are implementing IActionBase by just telling it you implement IAction1. Also when using a var of type IAction1 you can call members from IBaseAction becouse it knows it is implemented.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.