I've searched and not been able to find any solution to my problem. My scenario is very simple:
public class A
{
public virtual void MethodOne()
{
Console.log( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "C" );
}
}
What I am trying to do is have an instance of class C (we'll name it 'instanceC') call both the overridden method of its parent, and its grandparent. So I'd expect this:
instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"
But instead am getting this:
instanceC.MethodOne();
// Output
// "A"
// "C"
with class B's method being skipped over. Is this not possible? I thought this is the whole point of inheritance/polymorphism. Thanks in advance!
Your example works as expected for me. I see A B C. I think your most likely issue is that C doesn't extend B. However, let me suggest an arguably safer pattern while we're on the subject. You seem to want all overrides of MethodOne to execute code from their base classes. Great, inheritance is a good pattern for this. However, with this pattern you cannot force inheritors to execute the base logic because you cannot force them to call base.MethodOne(). Even if they do callbase.MethodOne(), you cannot ensure the order of the logic. Will they call base.MethodOne() at the beginning of the method, middle of the method, or end of the method? Often, in these types of patterns you want sub classes to execute all the base logic at the beginning of the function. The following pattern forces inheritors to execute base logic in the order base classes expect. It's technically less flexible but safer because inheritors must extend the base classes in a way that the base classes specify.
public class A
{
//Don't make this method virtual because you don't actually want inheritors
//to be able to override this functionality. Instead, you want inheritors
//to be able to append to this functionality.
public void MethodOne()
{
Console.WriteLine( "A" );
MethodToBeOverriddenOne();
}
//Expose a place where inheritors can add extra functionality
protected virtual void MethodToBeOverriddenOne() { }
}
public class B : A
{
//Seal the method because you don't actually want inheritors
//to be able to override this functionality. Instead, you want inheritors
//to be able to append to this functionality.
protected sealed override void MethodToBeOverriddenOne()
{
Console.WriteLine("B");
MethodToBeOverriddenTwo();
}
//Expose a place where inheritors can add extra functionality
protected virtual void MethodToBeOverriddenTwo() { }
}
public class C : B
{
protected sealed override void MethodToBeOverriddenTwo()
{
Console.WriteLine("C");
}
}
The example you posted works perfectly, whatever you are doing in your actual code is different than what you posted.
Here is your code running on ideone working as exactly like you wanted.
using System;
public class Test
{
public static void Main()
{
var c = new C();
c.MethodOne();
}
}
public class A
{
public virtual void MethodOne()
{
Console.WriteLine( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.WriteLine( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.WriteLine( "C" );
}
}
Related
For example, I have a class with interface, which has few methods.
What is the best way to call methods always only in a specific order in the class?
public class SomeClass
{
void Start(ISomeInterface testClass)
{
testClass.Method1();
testClass.Method2();
testClass.Method3();
}
}
public interface ISomeInterface
{
void Method1();//should run 2nd
void Method2();// 1st
void Method3();// 3rd
}
Take a look at Template Method Design Pattern
The intent of Template Method Design Pattern is to define the skeleton of an algorithm in an operation, deferring some
steps to client subclasses. Template Method lets subclasses redefine
certain steps of an algorithm without changing the algorithm's
structure.
abstract class SomeClass : ISomeInterface
{
public abstract void Method1();
public abstract void Method2();
public abstract void Method3();
// The template method
public void Start()
{
testClass.Method1();
testClass.Method2();
testClass.Method3();
}
}
class ImplementationClass : SomeClass
{
public override void Method1()
{
...
}
public override void Method2()
{
...
}
public override void Method3()
{
...
}
}
// Usage
var implementationClass = new ImplementationClass();
implementationClass.Start();
It's normal to write code so that methods are expected to run in certain order. But in that case we wouldn't want to just expose all of the methods and expect the caller to just "know" to run them in a certain order. If something is required then we must somehow enforce it.
If the methods of an interface can be executed in any order but in one specific case we want to run them in a particular order, that's easy. We just do them in the order we want:
testClass.Method2();
testClass.Method1();
testClass.Method3();
If methods must always be executed in a particular order then it doesn't make sense to expose an interface that allows us to execute them in just any order. The interface should describe how we want the class to be used. In that case this would make more sense:
public interface IDoesSomething
{
void DoSomething();
}
public class DoesSomething : IDoesSomething
{
public void DoSomething()
{
DoAnotherThing();
DoOneThing();
SomethingElse();
}
private void DoOneThing(){}
private void DoAnotherThing(){}
private void SomethingElse(){}
}
Now the interface tells other classes how to interact with it, but the details of how that gets done, which includes a particular sequence of steps, is encapsulated (hidden) inside the implementation of that class.
We're still doing the same thing - breaking a process into steps - but choosing how much of it we expose outside the class. We're making it easier to use our class correctly by making it impossible to use it incorrectly.
As far as I see, Template methodis not what you are looking for. (Unless you are one of those unpleasant people using answers without accepting ones ;))
If you'd like to give an illusion of freedom to a user and to punish one for using it wrong way, it could be done the following way.
Define an attribute:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class OrderAttribute : Attribute
{
public int Order { get; }
public OrderAttribute(int order) => Order = order;
}
Then define an interface:
public interface IObeyOrder
{
[Order(2)]
[Order(4)]
void Method1(); // should run 2nd or 4th
[Order(1)]
void Method2(); // 1st
[Order(3)]
void Method3(); // 3rd
void Method4(); // order doesn't matter
}
And implement it on a class, calling CheckOrder() first in each method:
public partial class ObeyOrder : IObeyOrder
{
public void Method1()
{
CheckOrder();
Console.WriteLine("Method1");
}
public void Method2()
{
CheckOrder();
Console.WriteLine("Method2");
}
public void Method3()
{
CheckOrder();
Console.WriteLine("Method3");
}
public void Method4()
{
CheckOrder();
Console.WriteLine("Method4");
}
public void Method5() // non-interface
{
CheckOrder();
Console.WriteLine("Method5");
}
}
where CheckOrder() is:
public partial class ObeyOrder : IObeyOrder
{
private static readonly Dictionary<string, int[]> orderedMethods = OrderHelper<IObeyOrder>.OrderedMethods;
private readonly Queue<int> orders = new Queue<int>(orderedMethods.Values.SelectMany(i => i).OrderBy(i => i));
private void CheckOrder([CallerMemberName] string methodName = "")
{
if (!orderedMethods.TryGetValue(methodName, out var methodOrders))
return;
var order = orders.Peek();
if (!methodOrders.Contains(order))
throw new Exception($"Wrong method call order. Method '{methodName}' with orders [{string.Join(", ", methodOrders)}]. Expected order {order}.");
orders.Enqueue(orders.Dequeue());
}
}
Of course, you can do it in a non-partial class.
public static class OrderHelper<T>
{
public static Dictionary<string, int[]> OrderedMethods { get; } = typeof(T)
.GetMethods()
.Select(method => new
{
Method = method.Name,
Orders = method.GetCustomAttributes(typeof(OrderAttribute), false)
.Cast<OrderAttribute>()
.Select(attribute => attribute.Order)
.ToArray()
})
.Where(method => method.Orders.Length > 0)
.ToDictionary(method => method.Method, method => method.Orders);
}
Usage:
var obeyOrder = new ObeyOrder();
obeyOrder.Method2(); // should go 1st
obeyOrder.Method4(); // can go whenever, since there is no order attribute
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method5(); // can go whenever, since it's non-interface
obeyOrder.Method3(); // should go 3rd
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method2(); // should go 1st (after the last had been already called)
works fine, but
var obeyOrder = new ObeyOrder();
obeyOrder.Method2(); // should go 1st
obeyOrder.Method4(); // can go whenever, since there is no order attribute
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method5(); // can go whenever, since it's non-interface
obeyOrder.Method3(); // should go 3rd
obeyOrder.Method1(); // should go 2nd or 4th
obeyOrder.Method2(); // should go 1st (after the last had been already called)
obeyOrder.Method2(); // should throw since the 2nd (obeyOrder.Method1()) is expected
throws
Wrong method call order. Method 'Method2' with orders [1]. Expected order 2.
First of all i think you got some concepts mixed up, a class implements an interface, you cannot have an interface class. What you do by implementing an interface is ensure that the consumer class of the interface has to implement that method signature in his code.
Secondly, there is no way to execute methods in a certain order if they re in an interface, this is because interface methods (not the code itself from each method, an interface does NOT HAVE ANY LOGIC on it). Probably what you are looking for here is class (can be abstract not sure why do you need an interface though), and you could have this 3 methods as private members of it and have a public method that executes the 3 of them. Like this:
public class Example
{
private void MethodA()
{
//logic from methodA
}
private void MethodB()
{
//logic from methodB
}
private void MethodC()
{
//logic from methodC
}
public void MethodA()
{
MethodB();
MethodA();
MethodC();
}
}
Only expose the callable methods in an interface, and return a new interface when the method has been called.
interface IMethod1 {
IMethod2 Method1();
}
interface IMethod2 {
IMethod3 Method2();
}
Initially, you return a IMethod1. This only exposes Method1(), so it's not possible to call Method2 out of order. When calling Method1(), it returns an IMethod2 that exposes Method2(), so that can be called.
These interfaces can be implemented by the same class, which exposes only some methods at a time through the various interfaces.
Edit: I wrote a blog post about this: Enforcing object lifecycles through interfaces
In C# it's possible to mark a virtual method abstract to force inherited class to implement it.
class A
{
public virtual void Method()
{
Console.WriteLine("A method call");
}
}
abstract class B : A
{
// Class inherited from B are forced to implement Method.
public abstract override void Method();
}
I would like to call the A implementation of Method from a class inherited from B.
class C : B
{
public override void Method()
{
// I would like to call A implementation of Method like this:
// base.base.Method();
}
}
The best way I find to do this is to add a protected method "MethodCore" in A implementation and call it when needed.
class A
{
public virtual void Method()
{
MethodCore();
}
protected void MethodCore()
{
Console.WriteLine("A method call");
}
}
abstract class B : A
{
public abstract override void Method();
}
class C : B
{
public override void Method()
{
MethodCore();
}
}
Is there any other way to do this ?
The best way I find to do this is to add a protected method "MethodCore" in A implementation and call it when needed.
Yes. Since you can't call an abstract method using base, all possible solutions are going to require you to eventually call Method in A using an A instance.
That said, it looks like you are looking for a way to provide a default implementation of Method in B such that any subclass of B that does not implement the method should simply use the implementation present in A. A better solution would be to not mark Method as abstract in B. Instead, make Method in B redirect to Method in A using base.Method()
abstract class B : A {
// Class inherited from B are forced to implement Method.
public virtual void Method() {
base.Method()//calls Method in A
}
}
This way, any subclass of B that wants to call Method from A can simply say base.Method().
If i am creating method with "override" property, derived method will not call base method implementation automatically and i will need to call it manually using "base" keyword like this:
public class A
{
public virtual void Say()
{
Console.Write("A");
}
}
public class B : A
{
public override void Say()
{
base.Say();
Console.Write("B");
}
}
So only in this case string "A" and "B" will be written to console. So the question is how can i get rid of "base.Say();" line? So i want to force every derived method "Say" to call base method from base class. Is it possible? I am looking for any solutions, even if i will be forced to use other keywords
Although it is not possible to achieve this directly, you could get the same effect by writing your own method that is not virtual, which calls the virtual after performing some fixed operation:
public class A
{
public void Say()
{
Console.Write("A");
SayImpl();
}
protected virtual void SayImpl()
{
// Do not write anything here:
// for the base class the writing is done in Say()
}
}
public class B : A
{
protected override void SayImpl()
{
Console.Write("B");
}
}
Now any class inheriting from A and implementing SayImpl() would have A prepended to its printout.
// Cannot change source code
class Base
{
public virtual void Say()
{
Console.WriteLine("Called from Base.");
}
}
// Cannot change source code
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
class Program
{
static void Main(string[] args)
{
SpecialDerived sd = new SpecialDerived();
sd.Say();
}
}
The result is:
Called from Special Derived.
Called from Derived. /* this is not expected */
Called from Base.
How can I rewrite SpecialDerived class so that middle class "Derived"'s method is not called?
UPDATE:
The reason why I want to inherit from Derived instead of Base is Derived class contains a lot of other implementations. Since I can't do base.base.method() here, I guess the best way is to do the following?
// Cannot change source code
class Derived : Base
{
public override void Say()
{
CustomSay();
base.Say();
}
protected virtual void CustomSay()
{
Console.WriteLine("Called from Derived.");
}
}
class SpecialDerived : Derived
{
/*
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
*/
protected override void CustomSay()
{
Console.WriteLine("Called from Special Derived.");
}
}
Just want to add this here, since people still return to this question even after many time. Of course it's bad practice, but it's still possible (in principle) to do what author wants with:
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
var ptr = typeof(Base).GetMethod("Say").MethodHandle.GetFunctionPointer();
var baseSay = (Action)Activator.CreateInstance(typeof(Action), this, ptr);
baseSay();
}
}
This is a bad programming practice, and not allowed in C#. It's a bad programming practice because
The details of the grandbase are implementation details of the base; you shouldn't be relying on them. The base class is providing an abstraction overtop of the grandbase; you should be using that abstraction, not building a bypass to avoid it.
To illustrate a specific example of the previous point: if allowed, this pattern would be yet another way of making code susceptible to brittle-base-class failures. Suppose C derives from B which derives from A. Code in C uses base.base to call a method of A. Then the author of B realizes that they have put too much gear in class B, and a better approach is to make intermediate class B2 that derives from A, and B derives from B2. After that change, code in C is calling a method in B2, not in A, because C's author made an assumption that the implementation details of B, namely, that its direct base class is A, would never change. Many design decisions in C# are to mitigate the likelihood of various kinds of brittle base failures; the decision to make base.base illegal entirely prevents this particular flavour of that failure pattern.
You derived from your base because you like what it does and want to reuse and extend it. If you don't like what it does and want to work around it rather than work with it, then why did you derive from it in the first place? Derive from the grandbase yourself if that's the functionality you want to use and extend.
The base might require certain invariants for security or semantic consistency purposes that are maintained by the details of how the base uses the methods of the grandbase. Allowing a derived class of the base to skip the code that maintains those invariants could put the base into an inconsistent, corrupted state.
You can't from C#. From IL, this is actually supported. You can do a non-virt call to any of your parent classes... but please don't. :)
The answer (which I know is not what you're looking for) is:
class SpecialDerived : Base
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
The truth is, you only have direct interaction with the class you inherit from. Think of that class as a layer - providing as much or as little of it or its parent's functionality as it desires to its derived classes.
EDIT:
Your edit works, but I think I would use something like this:
class Derived : Base
{
protected bool _useBaseSay = false;
public override void Say()
{
if(this._useBaseSay)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Of course, in a real implementation, you might do something more like this for extensibility and maintainability:
class Derived : Base
{
protected enum Mode
{
Standard,
BaseFunctionality,
Verbose
//etc
}
protected Mode Mode
{
get; set;
}
public override void Say()
{
if(this.Mode == Mode.BaseFunctionality)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Then, derived classes can control their parents' state appropriately.
Why not simply cast the child class to a specific parent class and invoke the specific implementation then? This is a special case situation and a special case solution should be used. You will have to use the new keyword in the children methods though.
public class SuperBase
{
public string Speak() { return "Blah in SuperBase"; }
}
public class Base : SuperBase
{
public new string Speak() { return "Blah in Base"; }
}
public class Child : Base
{
public new string Speak() { return "Blah in Child"; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Child childObj = new Child();
Console.WriteLine(childObj.Speak());
// casting the child to parent first and then calling Speak()
Console.WriteLine((childObj as Base).Speak());
Console.WriteLine((childObj as SuperBase).Speak());
}
}
public class A
{
public int i = 0;
internal virtual void test()
{
Console.WriteLine("A test");
}
}
public class B : A
{
public new int i = 1;
public new void test()
{
Console.WriteLine("B test");
}
}
public class C : B
{
public new int i = 2;
public new void test()
{
Console.WriteLine("C test - ");
(this as A).test();
}
}
You can also make a simple function in first level derived class, to call grand base function
My 2c for this is to implement the functionality you require to be called in a toolkit class and call that from wherever you need:
// Util.cs
static class Util
{
static void DoSomething( FooBase foo ) {}
}
// FooBase.cs
class FooBase
{
virtual void Do() { Util.DoSomething( this ); }
}
// FooDerived.cs
class FooDerived : FooBase
{
override void Do() { ... }
}
// FooDerived2.cs
class FooDerived2 : FooDerived
{
override void Do() { Util.DoSomething( this ); }
}
This does require some thought as to access privilege, you may need to add some internal accessor methods to facilitate the functionality.
In cases where you do not have access to the derived class source, but need all the source of the derived class besides the current method, then I would recommended you should also do a derived class and call the implementation of the derived class.
Here is an example:
//No access to the source of the following classes
public class Base
{
public virtual void method1(){ Console.WriteLine("In Base");}
}
public class Derived : Base
{
public override void method1(){ Console.WriteLine("In Derived");}
public void method2(){ Console.WriteLine("Some important method in Derived");}
}
//Here should go your classes
//First do your own derived class
public class MyDerived : Base
{
}
//Then derive from the derived class
//and call the bass class implementation via your derived class
public class specialDerived : Derived
{
public override void method1()
{
MyDerived md = new MyDerived();
//This is actually the base.base class implementation
MyDerived.method1();
}
}
As can be seen from previous posts, one can argue that if class functionality needs to be circumvented then something is wrong in the class architecture. That might be true, but one cannot always restructure or refactor the class structure on a large mature project. The various levels of change management might be one problem, but to keep existing functionality operating the same after refactoring is not always a trivial task, especially if time constraints apply. On a mature project it can be quite an undertaking to keep various regression tests from passing after a code restructure; there are often obscure "oddities" that show up.
We had a similar problem in some cases inherited functionality should not execute (or should perform something else). The approach we followed below, was to put the base code that need to be excluded in a separate virtual function. This function can then be overridden in the derived class and the functionality excluded or altered. In this example "Text 2" can be prevented from output in the derived class.
public class Base
{
public virtual void Foo()
{
Console.WriteLine("Hello from Base");
}
}
public class Derived : Base
{
public override void Foo()
{
base.Foo();
Console.WriteLine("Text 1");
WriteText2Func();
Console.WriteLine("Text 3");
}
protected virtual void WriteText2Func()
{
Console.WriteLine("Text 2");
}
}
public class Special : Derived
{
public override void WriteText2Func()
{
//WriteText2Func will write nothing when
//method Foo is called from class Special.
//Also it can be modified to do something else.
}
}
There seems to be a lot of these questions surrounding inheriting a member method from a Grandparent Class, overriding it in a second Class, then calling its method again from a Grandchild Class. Why not just inherit the grandparent's members down to the grandchildren?
class A
{
private string mystring = "A";
public string Method1()
{
return mystring;
}
}
class B : A
{
// this inherits Method1() naturally
}
class C : B
{
// this inherits Method1() naturally
}
string newstring = "";
A a = new A();
B b = new B();
C c = new C();
newstring = a.Method1();// returns "A"
newstring = b.Method1();// returns "A"
newstring = c.Method1();// returns "A"
Seems simple....the grandchild inherits the grandparents method here. Think about it.....that's how "Object" and its members like ToString() are inherited down to all classes in C#. I'm thinking Microsoft has not done a good job of explaining basic inheritance. There is too much focus on polymorphism and implementation. When I dig through their documentation there are no examples of this very basic idea. :(
I had the same problem as the OP, where I only wanted to override a single method in the middle Class, leaving all other methods alone. My scenario was:
Class A - base class, DB access, uneditable.
Class B : A - "record type" specific functionality (editable, but only if backward compatible).
Class C : B - one particular field for one particular client.
I did very similar to the second part of the OP posting, except I put the base call into it's own method, which I called from from Say() method.
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
BaseSay();
}
protected virtual void BaseSay()
{
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.BaseSay();
}
}
You could repeat this ad infinitum, giving, for example SpecialDerived a BaseBaseSay() method if you needed an ExtraSpecialDerived override to the SpecialDerived.
The best part of this is that if the Derived changes its inheritance from Base to Base2, all other overrides follow suit without needing changes.
If you want to access to base class data you must use "this" keyword or you use this keyword as reference for class.
namespace thiskeyword
{
class Program
{
static void Main(string[] args)
{
I i = new I();
int res = i.m1();
Console.WriteLine(res);
Console.ReadLine();
}
}
public class E
{
new public int x = 3;
}
public class F:E
{
new public int x = 5;
}
public class G:F
{
new public int x = 50;
}
public class H:G
{
new public int x = 20;
}
public class I:H
{
new public int x = 30;
public int m1()
{
// (this as <classname >) will use for accessing data to base class
int z = (this as I).x + base.x + (this as G).x + (this as F).x + (this as E).x; // base.x refer to H
return z;
}
}
}
The base class user should access the original method
class A
public init()
The derived class user should aceess ONLY the derived method.
class B
public init(int info)
I cannot use "override" bc there's a different signature.
What options do I have so that the derived class user does not see two methods.
Notes.
All in all I just need two classes that share some code. Inheritance is not a must.
But simplicity for the user of B is a priority.
This is a big code smell (and violates some basic OOP tenets) and, to the best of my knowledge, can not be done in any language. In OOP, an instance of B is an instance of A; this is polymorphism. So if A has a public method named init accepting no parameters, then so does B.
What are you trying to do this for?
Edit: Now that you've added the edit that states that inheritance is not a must, just use composition to share code. Give B a private instance of A, for example.
According to the Liskov principle you simply cannot do that, because it would violate this principle. The best thing you can to is override init() in the derived class and make it throw an exception every time it's invoked, stating that the user should use init(int info) and rely on the test to catch the errors.
Why you can't simple replace the init() method or even make it protected?
The Liskov principle states (rephrased) that where an instance of class A is required, an isntance of class B extends A can be passed.
If a method expects A and wants to call init() on it and you pass B (which extends A) to it with a protected init() the method will fail. This is the reason why the code will not even compile.
What you're asking for is impossible, due to the nature of the type system. Any instance of B can be thought of as an A, so you can call any of A's methods (including Init()). The best you can do is overload Init() in B and throw an exception to catch this at runtime.
public class B
{
void Init()
{
throw new NotSupportedException();
}
}
Contrary to some answers/comments here, what you are asking for would have a real use if it existed:
class Derived : Base
{
This can be seen by considering the workaround:
class Derived
{
private Base _base = new Base();
In other words, it's not really a base class at all, but a hidden part of the implementation.
The downside with this workaround is: what Base has an abstract method that you have to supply? You have to write this:
class Derived
{
class ActualDerived : Base
{
// override abstract method(s)
}
private Base _base = new ActualDerived();
This is the whole point of private inheritance (as found in C++) - it's for situations when you want to inherit the implementation but not the "interface" (in the informal sense).
But in C#, it's not available.
Presumabely A and B have something in common. Can you factor that out into a different base class?
public class Base
{
... common stuff ...
}
public class A : Base
{
public void Init()
{
}
}
public class B : Base
{
public void Init(int info)
{
}
}
if you need polymorphism then references to Base or, better yet, Thomas' interface are the way to go.
Instead of inheritance, use an interface as a "middle man":
public interface IAllThatYouNeed
{
public void DoSomeStuff();
}
public class A : IAllThatYouNeed
{
public void Init() {
// do stuff
}
}
public class B : IAllThatYouNeed
{
public void Init(int info) {
// do stuff
}
}
it looks like it's not yet possible
i tried to do something like this:
public class B : A
{
private override void Init() { }
public void Init(int x)
{ }
}
but Init() it's still visible from the A class
There is no perfect solution here. Some possible ways to do it:
An approach would be to make A.Init() virtual, override it in B and make it throw a NotImplementedException/InvalidOperationException.
Init() stays visible, but the user finds out very quickly that it is not to be used (make it explicit that Init(int info) is to be used in the XML documentation and in the message of the exception).
If you don't care about the inheritance part and just want to use the functionalities of class A in class B, don't have B deriving from A and make B instantiate A and use its functionalities.
Edit:
You can use an interface implementing the common operations in order to retain inheritance while avoiding to implement Init() in B:
public interface IOperations
{
void DoStuff();
void Foo();
}
public class A : IOperations
{
public void Init()
{
// Do class A init stuff
}
#region IOperations Members
public void DoStuff()
{
// ...
}
public void Foo()
{
// ...
}
#endregion
}
public class B : IOperations
{
A _operations = new A();
public void Init(int initData)
{
_operations.Init();
// Do class B init stuff
}
#region IOperations Members
public void DoStuff()
{
_operations.DoStuff();
}
public void Foo()
{
_operations.Foo();
}
#endregion
}
This can be made even better by using a factory:
public static class OperationsFactory
{
public static IOperations CreateOperations()
{
A result = new A();
result.Init();
return result;
}
public static IOperations CreateOperations(int initData)
{
B result = new B();
result.Init(initData);
return result;
}
}
This way instantiation code is well encapsulated, the difference between the two Init() methods is hidden from the user code.