How to automaticly provide constructors from generic base class in C#? - c#

So I have a generic base class like this:
class DatabaseDatasourceClassBase<DomainClass>
where DomainClass : new()
{
protected DomainClass m_DbObject;
public AddableDatabaseDatasourceClassBase()
{
m_DbObject = new DomainClass();
}
public AddableDatabaseDatasourceClassBase(DomainClass initialObject, ISessionWrapper dbSession)
{
m_DbObject = initialObject;
//Do stuff like calling SetSession(dbSession);
}
//Several functions and stuff like SetSession(ISessionWrapper dbSession)
}
I also got a lot (>20) of datasource-classes for the use in wpf-datagrids.
class CurrencyDatasource : AddableDatabaseDatasourceClassBase<Currency>
{
//The constructors look always the same
public CurrencyDatasource()
:base()
{
}
public CurrencyDatasource(Currency initialExchange, ISessionWrapper dbSession)
:base(initialExchange, dbSession)
{
}
//Following Properties are always different
public string Name
{
get
{
return m_DbObject.Name;
}
set
{
m_DbObject.Name = value;
}
}
}
So I wonder if there is a way to avoid having to write the same code (the 2 constructors + their call to the base class) in every Datasource class?
or
If this is not possible:
At least define that all classes which are derived from DatabaseDatasourceClassBase have to have these 2 Constructors?

So I wonder if there is a way to avoid having to write the same code (the 2 constructors + their call to the base class) in every Datasource class?
Each class must provide their own constructor(s) and define how they wish to call the base class's constructor(s).
At least define that all classes which are derived from DatabaseDatasourceClassBase have to have these 2 Constructors?
Classes must call at least one base class constructor, but there is no way to enforce which one, or require more than one base constructor be hooked up.
That's at least in code.
I guess you could do something crazy with static code analysis.

Related

Design pattern for overcoming the reverse constructor order?

I have the following problem:
The base class expects to receive some data but the data is initialized by the derived class constructor which in C# is called after the base constructor was called.
Context / What I'm trying to solve:
Let's call the base class Track, its role is to build a mesh that represents a track for a video game.
The derived classes, e.g. Track1 each fetch track data from a particular file format, with significant differences that forbids implementing the whole code in base class Track.
The main job of Track is to abstract the data incoming from derived classes and for this it has abstract members that derived classes have to implement, e.g. int GetVertexCount, Vector3 GetVertex(int).
Think more of less of it being an IPicture interface that can load from different formats, e.g. BMP, JPEG, and return the whole thing as an abstraction.
The problem I am facing:
In C#, base class constructors are called before derived class constructor, but I must initialize something in the derived class constructor that in turn I must pass to the base class constructor. And while I'm on it, I would like to have members to be immutable, i.e. readonly.
Question:
How can I run some code in derived class constructor first, so I can pass the result to the base constructor ?
Answer:
Following #Kit answer here's how I ended up doing and it's just fine:
Ironically, it ended up being a C-like API :)
Assuming you don't need an instance of your derived class to do the logic you want, you can call a static method from your derived constructor prior to calling the base constructor.
Here is a simplistic example
public class Base
{
protected Base(SomeType data)
{
// base logic using data
}
}
public class DerivedOne : Base
{
public DerivedOne(int some, string data) : base(DerivedLogic(some, data))
{
...
}
private static SomeType DerivedLogic(int some, string data) => ...
}
public class DerivedTwo : Base
{
public DerivedTwo (string moreStuff) : base(DerivedLogic(moreStuff))
{
...
}
private static SomeType DerivedLogic(string moreStuff) => ...
}
This runs in the following order:
Static method DerivedLogic
Base class constructor (using the value from DerivedLogic)
Derived constructor
Now, that's slightly weird. What might be better is the derived logic not be a part of the derived class at all. What do I mean? I mean you have a third class that is passed into the derived constructor, and then on to the base constructor. That gives you the same effect.
public class Base
{
protected Base(SomeOtherType dataWrapper)
{
var data = dataWrapper.DerivedLogic();
// base logic using data
}
}
public class DerivedOne : Base
{
public DerivedOne(SomeOtherType otherType) : base(otherType)
{
...
}
}
Or calculate SomeType somewhere prior to calling any constructors and then pass it in. Either of these ways is a better design because it follows SRP:
Base class responsible for what it does.
Logic for constructing a track has that single responsibility.
Derived class has it's single responsibility.
There's not a really elegant way to do exactly what you're asking for, but I would question whether it's really necessary. It's usually a code smell to see logic in a constructor.
There are lots of other approaches you can take, like using a static Create() method.
class Derived : Base
{
private readonly object _o;
private Derived(object o, string s) : base(s)
{
_o = o;
}
public static Derived Create(string path)
{
var o = new object();// initialize from path
var s = o.ToString(); // get s from o.
return new Derived(o, s)
}
}
You could also consider using composition over inheritance:
class Base
{
private readonly string _s;
public Base(string s)
{
_s = s.ToLower();
}
}
class Derived
{
private readonly object _o;
private readonly Base _b;
public Derived(string path)
{
_o = new object();// initialize from path
_b = new Base(_o.ToString());
}
}
But it's really difficult to know which of these approaches might be appropriate without knowing what your actual goals and constraints are. You've told us how you want to solve your problem, and not what problem you're trying to solve.

Calling a method from the getter of a property

Is there a way I can define a method, that is called in every case, when a getter for any property in a class is called?
The class is a base class, and I want to implement various SubClasses of it, but each one should have in common that regardless of the property that should be accessed by its getter function, an action should be performed before the attribute is returned.
No, not unless you code it into every Getter, or you abandon "Plain Old C# Classes" altogether and construct a data model paradigm based around a read-audited set of data. If you go down that route that you simply have each "data class" being an Dictionary of Get/Set delegates and access its data values through those delegates. Its not an uncommon design, but it no longer follows the OO paradigms.
Example (psuedo code)
public class MonitoredCustomerObject
{
// Assumption that the Get/Set delegates are stored in a simple Tuple.
private Dictionary<string, Tuple<delegate,delegate>> getterSetterDict = new ...
public GetValue(string key)
{
executeMyOnReadCode();
return getterSetterDict[key].Item1();
}
public SetValue(string key)
{
executeMyOnWriteCode();
getterSetterDict[key].Item2();
}
}
You can kind of fake this, or you can write a Fody extension that does it. For example, you can have your base class defined as:
public abstract class MyBaseClass
{
public object MyProperty
{
get
{
RunSomeMethod();
return MyPropertyValue;
}
}
protected abstract object MyPropertyValue { get; }
}
Which "kind of" forces the implementer to write it like:
public class MyDerivedClass : MyBaseClass
{
protected override object MyPropertyValue
{
get
{
return SomeObjectValue();
}
}
}
The derived class can still hide the base class properties with new, but at least that causes the developer to explicitly realize that they are doing something unintended.

How can I set derived static members before calling static functions of the base class

I have the following class:
class Base<T> where T : Base<T>
{
protected static string Source;
public static List<T> Read()
{
return GetResource(Source);
}
}
I want this class as baseclass for its functionality but every derived class has to have a different Source. My problem is that I can't assure the Source is set before Read is called. I know I could ask if the Source is set before GetResource is called but that's not the point. I need it to be set before any static member of my class is called.
Generic parameters can't have static Members so I can't take it from there.
I tried setting the Source in the derived class's static constructor but that will only be called when I call a member that is in the derived class and not in the Base.
I tried using a overridable method inside of the static Base constructor but such a method has to be static as well and static methods can't be overwritten.
When I set the Source manually, there is a chance that the Read-Function has already been called, so I have to set the Source before it can be called.
I know I could give Source as a parameter in Read but I want Read to be used without parameters.
Is there any way I can assure that the Source is Set before any other Member of my class is called, so that any dependent code is inside the derived class and doesn't have to be called by anyone using a derived class?
I basically want it to work like this:
class Derived : Base<Derived>
{
// somehow set Source
Source = "This is my source";
}
class User
{
private List<Derived> MyResources;
public User()
{
MyResources = Derived.Read();
}
}
Note: the Source is basically a SQL statement so an Attribute or something like that wont be sufficient I think.
Ok, I found an answer. It is not as pretty as I hoped it would be but its the best I could come up with.
I will use an interface to force an Instance of T to have a certain method that provides my source.
interface ISource
{
string GetSource();
}
I then implement that into my base class as such:
class Base<T> where T : Base<T>, ISource, new()
{
public static List<T> Read()
{
// here I create an Instance to be able to call the Methods of T
string source = (new T()).GetSource();
return GetResource(source);
}
}
The derived class:
class Derived : Base<Derived>, ISource
{
public string GetSource()
{
return "This specific source";
}
}
Usage as such:
class User
{
public User()
{
List<Derived> myResources = Derived.Read();
}
}
This of course will lead to every instance of Derived having the GetSource-method but for my scenario thats not a big deal.
Also, since it creates an instance in the Read-method, this could be time consuming depending on the constructor of Derived. In my scenario it only has the standard constructor.
So use with caution.

Should I declare properties as Interfaces or as Base classes (when they implement both)?

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.

How to define virtual method with return type which is not void in C#

This might sound like a dumb question, but I need to write a virtual method that is being overridden by inherited class. I don't need the virtual method to have any code, since this method is fully dependent on inherited class, therefore all code will be in the override methods.
However, the method has a return type that is not void. If I keep the virtual method empty it would give me an error "no all path return a value".
The only solution I came up with was to implement the virtual method with returning a dummy empty string, but I don't feel this is the best way. Is there any other way to define a virtual method with return type?
Edit:
Even most answers were correct in their own way, they did not help in my case, therefore I am adding snippets of the code which shows why I need to create instance of the base class, and why I can't use interface, or abstract:
//base class
public class Parser
{
public virtual string GetTitle()
{
return "";
}
}
//sub class
public class XYZSite : Parser
{
public override string GetTitle()
{
//do something
return title;
}
}
// in my code I am trying to create a dynamic object
Parser siteObj = new Parser();
string site = "xyz";
switch (site)
{
case "abc":
feedUrl = "www.abc.com/rss";
siteObj = new ABCSite();
break;
case "xyz":
feedUrl = "www.xzy.com/rss";
siteObj = new XYZSite();
break;
}
//further work with siteObj, this is why I wanted to initialize it with base class,
//therefore it won't break no matter what inherited class it was
siteObj.GetTitle();
I know the way I cast Parser object to Site object doesn't seem very optimal, but this is the only way it worked for me, so Please feel free to correct any thing you find wrong in my code.
Edit (Solution)
I followed the advice of many of replies by using interface and abstract. However it only worked for me when I changed the base class to abstract along with all its methods, and inherited the base class from the interface, and then inherited the sub classes from the base class. That way only I could make sure that all classes have the same methods, which can help me generate variant object in runtime.
Public interface IParser
{
string GetTitle();
}
Public abstract class Parser : IParser
{
public abstract string GetTitle();
}
Public class XYZ : Parser
{
public string GetTitle();
{
//actual get title code goes here
}
}
//in my web form I declare the object as follows
IParser siteObj = null;
...
//depending on a certain condition I cast the object to specific sub class
siteObj = new XYZ();
...
//only now I can use GetTitle method regardless of type of object
siteObj.GetTitle();
I am giving the credit to CarbineCoder since he was the one who put enough effort to take me the closest to the right solution. Yet I thank everyone for the contribution.
You can throw NotImplementedException instead of returning object:
public virtual object Method()
{
throw new NotImplementedException();
}
But if you are not implementing anything in virtual method you can create abstract instead of virtual:
public abstract object Method();
Edit:
Another option is to create interface for it.
public interface IMethods
{
object Method();
}
And make your classes children of this interface.
you need to use abstract here. The abstract modifier indicates that the thing being modified has a missing or incomplete implementation.
public abstract returntype MethodName();
But as you say, 'since this method is fully dependent on inherited class, therefore all code will be in the override methods', than if you are really going to override the functionality of the method in inherited class, why do you care if the method returns dummy or stuff? (e.g: you can make it virtual and get going)
Edit: as you cannot mark class as abstract, you can use virtual method instead.
public virtual returntype MethodName()
{
.....
return xyz;
}
(just for info: An abstract member is implicitly virtual. and abstract is sort of pure virtual. so you need virtual, instead of pure virtual)
Since other answers have discussed about abstract/virtual implementation, I am suggesting my own version.
There is a contradiction in your requirement.
You want a base class which is not an abstract but it has a method which is not implemented. Don't you think this unimplemented method will make the class incomplete and end up making it an abstract one even though you haven't explicitly said so?
So lets assume your class will never be an abstract class and its perfectly reasonable to have it as a normal class. Does it make sense to remove this method from the class altogether and move it to an interface?
Can you try extracting this method and put it into an interface.
interface NewInterface
{
string NewMethod();
}
public BaseClass
{
...
}
public DerivedClass : BaseClass, NewInterface
{
public string NewMethod
{
...
}
}
If you can do this, then you need not have to worry about the base class being abstract/ having NotImplemented exception, only downside is every derived class should implement this interface, but thats the point of making the base class non-abstract.
I don't see any problem in implementing Abstract BaseClass/ Interface for your approach. Both are supposed to be the solution for your problem.
//Parser siteObj = new Parser(); - Dont initialize it here,
//your are initializing it once more below
NewIterface siteObj;
string site = "xyz";
switch (site)
{
case "abc":
feedUrl = "www.abc.com/rss";
siteObj = new ABCSite();
break;
case "xyz":
feedUrl = "www.xzy.com/rss";
siteObj = new XYZSite();
break;
}

Categories

Resources