I'm looking for a way to share the implementation of two classes without exposing any details of that sharing. I was hoping to create this basic class structure:
public interface MyInterface
class MyCommonImpl : MyInterface
public class MyImplA : MyCommonImpl
public class MyImplB : MyCommonImpl
MyCommonImpl implements the functions of MyInterface and has one abstract function provided in MyImplA and MyImplB. A user of MyImplA should not know about MyCommonImpl in any fashion, it's just an implentation detail.
I've considered doing manual composition, but this involves copying a lot of code to forward the functions. It's also problematic since there are events implemented in MyCommonImpl, and one of their parameters is a sender. This requires putting a proxy handler and partially rewriting events. Basically composition would require more code than simply copy-pasting the entire MyCommonImpl.
How can I do this without having to duplicate a lot of code?
You can move the interfaces and implementations to another assembly and mark them internal which will hide the abstract function of MyCommonImpl. Taking it further, you could explicitly implement the interfaces inside that assembly to completely hide their methods from callers leaving only those methods declared public on MyImplA visible.
The internal casts for the explicit implementation are a bit nasty though...
In a separate assembly:
namespace Private
{
internal interface IMyInterface
{
void InterfaceMethod();
}
public abstract class MyCommonImpl : IMyInterface
{
internal MyCommonImpl()
{
// internal ctor to stop callers constructing
}
void IMyInterface.InterfaceMethod()
{
Console.WriteLine("InterfaceMethod");
}
internal abstract void CommonAbstract();
}
public class MyImplA : MyCommonImpl
{
internal override void CommonAbstract()
{
((IMyInterface)this).InterfaceMethod();
Console.WriteLine("CommonAbstract");
}
public void ImplAMethod()
{
CommonAbstract();
Console.WriteLine("ImplAMethod");
}
}
}
Related
I'm honestly looking for good examples here of reasons to use interfaces over abstract. And the main reason I can see is they are unopinionated public blueprints for classes to follow. But with them adding default implementations thats no longer true. Its becoming more and more difficult to distinguish interfaces from abstract classes. Genuinely whats the point in using an interface over an abstract class in c# 11. Its just a slower abstract class.
Even I find abstract classes and interfaces are too similar. I prefer using abstract classes, as its methods can be defined, until and unless there's the concept of multiple inheritance used.
As with case of abstract classes, we can't inherit from multiple abstract classes, whereas with interfaces, you could inherit as many interfaces you wish.
I'll let you understand this through a patch of code.
interface IFirstInterface
{
void myMethod();
}
interface ISecondInterface
{
void myOtherMethod();
}
class Democlass : IFirstInterface, ISecondInterface
{
public void myMethod()
{
System.Console.WriteLine("Some text..");
}
public void myOtherMethod()
{
System.Console.WriteLine("Some other text..");
}
}
class Program
{
static void Main(string[] args)
{
Democlass myObj = new Democlass();
myObj.myMethod();
myObj.myOtherMethod();
}
}
Lemme know if you find this unclear.
I have a class using a group of properties in similar ways (only two shown in the example, for brevity).
The general behavior is defined on a base class, while the specific behavior is defined in specific interfaces
The problem is: If I declare them as base class, I have to cast them to interface to call interface methods. Now if I declare them as interface, I have to cast them to base class when I want to call base methods.
My goal when using interfaces here is to improve testability (with dependency injection, later), and to cultivate the habit of "programming to the interface", but I cannot decide which way is best, or even if the whole rationale is good in the first place.
public class Conductor
{
// These properties inherit from base class
// and implement one specific interface each:
// declared as interface:
IPlotterHelper _plotter_helper = new PlotterHelper();
// declared as base class:
Helper _file_writer_helper = new FileWriterHelper();
// When using handlers defined in specific interfaces:
// have to cast this:
this.NewFrame += ((IPlotterHelper)_file_writer_helper).ProcessFrame();
// but not this:
this.NewSamples += _plotter_helper.ProcessSamples();
// While when using handlers from the base class
// have to cast this to the base class (since it is an interface):
this.CommandSent += ((Helper)_plotter_helper).RunCommand;
// but not this:
this.CommandSent += _file_writer_helper.RunCommand;
}
internal class FileWriterHelper : Helper, IFileWriterHelper
{
IFileWriterHelper.ProcessFrame()
{
// ...
}
// ...
}
internal class PlotterHelper : Helper, IPlotterHelper
{
IPlotterHelper.ProcessSamples ()
{
///
}
// ...
}
internal class Helper
{
internal void RunCommand()
{
// ...
}
}
When I am faced with the desire to have default behavior in an interface, I would generally consider using an abstract base class either with protected helper methods and a set of abstract interface methods or a default implementations of the "interface" methods. This may be the case even if I start with only a single concrete implementation.
Many people treat abstract classes and interfaces as being in the same broad category of implementation options.
The problem with abstract classes is single inheritance, so we should only use an abstract class if it really is to be the base of a class hierarchy (even a shallow one). Interfaces can be used to decorate classes (from diverse hierarchies) with common behavior.
For testing, I don't see much difference between faking with an interface and faking with an abstract class - but that might depend on your testing infrastructure.
In this case, I would use an abstract class and forget about the interface (unless it already exists, in which case you don't have any choice anyway).
It's hard to exactly see what you're trying to do, but it seems like this might be a more suitable design:
public class Conductor
{
private IPlotterHelper _plotter_helper = new PlotterHelper();
private IFileWriterHelper _file_writer_helper = new FileWriterHelper();
public void Conduct()
{
_file_writer_helper.ProcessFrame();
_file_writer_helper.RunCommand();
_plotter_helper.ProcessSamples();
_plotter_helper.RunCommand();
}
}
internal interface IHelper
{
void RunCommand();
}
internal interface IFileWriterHelper : IHelper
{
void ProcessFrame();
}
internal interface IPlotterHelper : IHelper
{
void ProcessSamples();
}
internal class FileWriterHelper : Helper, IFileWriterHelper
{
public void ProcessFrame()
{
}
}
internal class PlotterHelper : Helper, IPlotterHelper
{
public void ProcessSamples()
{
}
}
internal class Helper : IHelper
{
public void RunCommand()
{
}
}
Interfaces and abstract classes have the same purpose: provide abstraction. Make that abstraction coherent, and if the base class has public members, make sure they're also on the interface.
But then, why would I need the abstract class or interface for? - right. get rid of either the base class or the interface - you likely don't really need both. I'd drop the base class.
Why is this code (ImplementingClass) not valid?
What the are the issues that prevent this from being supported? Shouldn't a subclass (InterfaceD) be able to take in more than the superclass (InterfaceC), and use the same method? When something of type InterfaceD is used as type InterfaceC, all inputs will be handled fine. But InterfaceD would be able to handle other scenarios (objects of ClassA) too instead of just some (ClassB).
I know I can just implement both methods on ImplementingClass and pass off the call to the InterfaceD method, but why does the compiler demand that?
public class ClassA
{
// ...
}
public class ClassB : ClassA
{
// ...
}
public interface InterfaceC
{
void MethodA(ClassB)
}
public interface InterfaceD : InterfaceC
{
void MethodA(ClassA);
}
public class ImplementingClass : InterfaceD {
void MethodA(ClassA)
{
// ...
}
// refuse to implement MethodA(ClassB) ...
}
Edit: A simpler example might be if InterfaceD did not exist, and I tried to just implement InterfaceC with the MethodA(ClassA)
You have to implement MethodA(ClassB) because InterfaceD inherits from InterfaceC therefore InterfaceD now has MethodA(ClassB) and MethodA(ClassA) just like you can access methods of ClassA through an instance of ClassB.
The best approach would be to not derive InterfaceD from InterfaceC and have ImplementingClass implement the interfaces that it requires. Without seeing a concrete example its hard to comment, but it basically would come down to the design of you interfaces.
I have no practical experience with OO design, thus I am hesitant as to the solution I adopted for the following problem:
I have to process network text files that come from N different sources, in different formats - with the processing consisting in the classical reading, computations, and insertion into database.
The solution I devised was to create a class that defines all functionalities/behaviors that are core/file-format-independent, and create derived classes from the latter where each contain the appropriate format-reading logic, according to the file-type the given class handles.
All files are read via File.ReadAllLines(), what differs is mapping fields from the file into the main object's variables. So I did this by defining an event in the base class, that is called after File.ReadAllLines(), and all derived classes attach their mapping logic to the inherited event.
But I understand this solution is not correct design-wise. First of all, there is no meaning in instantiating the base class, so it should be abstract. The reason I did not make it abstract is that the construction code for all the derived objects is the same, so I defined it as the base constructor. Should I declare an "Initialize" method in the abstract class and simply call it in every derived class's constructor? (looks weird...)
Perhaps interfaces? I don't see how using an interface would give me any benefits here, besides it will not solve this "constructor" problem...
What is the correct solution?
Code demonstration of my scenario:
public delegate void myDelegate(object parameter);
class Base
{
#region Attributes
...
#endregion
public Base(object p)
{
//initialization code
...
}
#region Methods
protected void m1() { }
protected void m2() { }
...
#endregion
public event myDelegate myEvent;
}
class Child1
{
public Child1(object o) : base(o)
{
this.myEvent += new myDelegate(ChildMethod);
}
public void ChildMethod(object o)
{
...
}
}
First of all, there is no meaning in instantiating the base class, so it should be abstract. The reason I did not make it abstract is that the construction code for all the derived objects is the same, so I defined it as the base constructor.
You still can make the base class abstract yet have common constructor logic in the base class constructor. I see in your code you've already figured out how to call the base class constructor; that's all you need to do.
abstract class Base {
public Base(object o) { }
public abstract void M();
}
class Derived : Base {
public Derived(object o) : base(o) { }
public override void M() { }
}
I have many classes in a project that need to all have a base set of the same constructors and 1 public method. Below is an example of this partial class:
public partial class SHIPMENT_LINE
{
private OracleConnection _rp = null;
private EntityConnection _rpe = null;
private static string _schema = "";
public SHIPMENT_LINE() { }
public SHIPMENT_LINE(BHLibrary.Configuration.ConnectionOption Environment)
{
SetConnection(Environment);
}
public void SetConnection(BHLibrary.Configuration.ConnectionOption Environment)
{
this._rp = Configuration.RPConnection(Environment);
this._rpe = Configuration.RPEntityConnection(Environment, out _schema);
}
}
I need to implement the same private variables, constructors, and the SetConnection method on each of my classes that I create. After this all exists in each class, then each class will do something different, so the classes are not all necessarily related, aside from the fact that they all have this same "Beginning."
How should I go about building each of these classes so that I do not have to implement this SetConnection method in each of the classes that I create?
Keep this in mind:
Due to other restrictions, I cannot inherit from another class in any of these classes. I can, however, use Interfaces if necessary.
I would suggest going for composition rather than inheritance...
Make each of the class implement an interface, then have another class (not related to these) which also implements the interface and has a concrete implementation of it. All the classes you've mentioned above should have an instance of this additional class and just call through to it.
Example
public partial class SHIPMENT_LINE : ISetConnection
{
private ConnectionSetter connector = new ConnectionSetter();
public void SetConnection(BHLibrary.Configuration.ConnectionOption Environment)
{
this.connector.SetConnection(Environment);
}
}
public class ConnectionSetter : ISetConnection
{
public void SetConnection(BHLibrary.Configuration.ConnectionOption Environment)
{
// Implementation
}
}
If you can't subclass then an abstract class is not a viable solution and interfaces are only going to give you the contract that your common classes conform to without any implementation.
I would suggest implementing the common functionality in a common class and using this as a private member in your other classes (I.E. composition rather than inheritance). Your other classes could all implement an interface to ensure they all have the same methods and they could just forward their calls onto the private classes implementation of the method.
E.G.
private MYClassWithCommonFunctionality xyz = new MYClassWithCommonFunctionality();
And then...
Private void MyCommonInterfaceMethod(object param)
{
// Do derived class specific stuff here...
xyz.MyCommonInterfaceMethod(param);
}
And as an added bonus and a bit of forward thinking....have the common class also share the same interface and pass an implementation of this into your other classes constructor. That way in the future you can swap the implementation for another.
If you cannot create a base class that will implement your common functionality (any reason why?) than you probably can use T4 template to generate partial class with your common methods.