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.
Related
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.
I have a BaseClass, which implements a method to populate itself form a different data structure. SubClasses will add their properties to the base ones. I want all sub-classes and sub-sub...classes to implement their own version of the method and call their parent class to do the same. So this is not just overriding, I want to force the implementation, but each implementation of the method has to be called, not just overridden.
Sort of like:
class BaseClass
{
int id;
virtual void fromDictionary(Dictionary data)
{
id = data["id"];
}
}
class Derived1 : BaseClass
{
string name;
override void fromDictionary(Dictionary data)
{
name = data["name"];
base.fromDictionary(data);
}
}
class Derived2 : Derived1
{
float size;
override void fromDictionary(Dictionary data)
{
size = data["size"];
base.fromDictionary(data);
}
}
Then doing this:
Derived2 object = new Derived2();
object.fromDictionary(dictionary);
Populates all of the object's properties.
I can make the first one virtual and override in the derived ones, but that doesn't force the implementation. And making an abstract base above this base or using an interface wouldn't force ALL levels of inheritance to implement.
The ideal case would be forcing all derived classes to implement their version AND call their parent's version (or even better, have some sort of extension/overriding that automatically calls ALL implementations of the method from the instantiated object's class upwards).
How close to that can I get ?
Seeing why you need this kind of overriding I strongly believe that you should try to move this logic to a constructor because as it looks now:
Derived2 object = new Derived2();
object.fromDictionary(dictionary);
Your object will only be valid if it has a dictionary. So instead of constructing it from a dictionary using a method, you should provide a constructor which receives a dictionary as a parameter:
Derived2 object = new Derived2(dictionary);
Now you have a valid object from the beggining. There are more reasons why you should do this instead of using a method which composes your object, one as you observed is that each subclass will need to call the base method, and having this kind of constructor (assuming that you will not provide a parameterless one) will force the inheritors to call the base one.
Another advantage in using this kind of approach is that you will have a valid object form the beginning instead of making it possible for users of that classes to make invalid objects by forgetting to call the fromDictionary() method.
Thanks for the suggestions everyone, the closest I could get is:
public abstract class DAO
{
public long id { get; set; }
public void fromDictionary(Dictionary<string, object> obj)
{
//Does own part in the method
id = (long)obj["id"];
//Calls most derived implementation
fromDictionaryOperation(obj);
}
//Forces child to implement its part
protected abstract void fromDictionaryOperation(Dictionary<string, object> obj);
}
//Is forced to implement its part, and the base implementation will be executed always
public class Area : DAO
{
public string name { get; set; }
protected override void fromDictionaryOperation(Dictionary<string, object> obj)
{
name = (string)obj["name"];
}
}
//Is NOT forced to implement method, and MUST call base.fromDictionary() for all this to work properly, but is NOT FORCED TO.
public class CircularArea : Area
{
public float radius { get; set; }
protected override void fromDictionaryOperation(Dictionary<string, object> obj)
{
radius = (float)obj["radius"];
base.fromDictionary(obj);
}
}
So all 2nd generation classes will be fine, but subsequent sub-classes wont be forced to implement its part or call the parent implementation. Which means that if in an implementation of a sub-sub-class, the base.fromDictionary() method is not called, then all parent classes implementation, except the first/base class, will be skipped without any compiling warning or error.
To force implementation at all levels, I guess I could put the abstract method in an Interface and make all classes implement the interface, which can't be forced itself, but is as close as I can think of.
If anyone knows a way to completely force ALL of them to implement the same method, that would be top notch.
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.
I'm trying to create a class with the name ForumHolderAdminController. ForumHolderAdminController provides a collection of controller types to the parent class CmsAdminController.
I have the following code:
public abstract class CmsAdminController : Controller {
// The type of child controllers allowed
protected Collection<Type> AllowedChildren {
get { return null; }
}
}
public class ForumHolderAdminController : CmsAdminController {
protected new Collection<Type> AllowedChildren {
get {
Collection<Type> allowedChildren = new Collection<Type> {
typeof(ThreadHolderController)
};
return allowedChildren;
}
}
}
I would like to restrict developers to passing a collection of types that implement the IController interface. Something similar to the following:
protected new Collection<IController> AllowedChildren {
get {
Collection<IController> allowedChildren = new Collection<IController> {
typeof(ThreadHolderController)
};
return allowedChildren;
}
}
Obviously the code example won't work because there is no instance being created. But I would like something similar to this where you don't have to create an instance of an object, you just have to pass the type.
I did see the following question which appears to be somewhat relevant, however one of the comments suggests using static analysis of the type before adding it to the collection:
Type-safe collection of Type class with defined base type
If I have to perform a static analysis this leaves me with a problem. If the developer passes a type that hasn't implemented the IController interface we won't know there is a problem with the code until it is executed. I would prefer it there was a compile error preventing developers from passing a collection of types where one or more don't implement the IController interface.
Therefore, is it possible to restrict developers to passing a collection of types that implement the IController interface?
You could come pretty close to what you want to do by returning a custom class that wraps the Type, and which can only be instantiated for generic types that implement IController:
public class ControllerTypeWrapper<T> : ControllerTypeWrapper
where T : IController
{
public Type Type {get {return typeof(T);}}
}
public class ControllerTypeWrapper
{
// This should only be extended by ControllerTypeWrapper<T>
internal ControllerTypeWrapper(){}
}
Then your AllowedChildren property should return these wrappers, and whatever's consuming it can simply use the.Type` property off of the results:
protected new IReadOnlyCollection<ControllerTypeWrapper> AllowedChildren {
get {
return new List<ControllerTypeWrapper> {
new ControllerTypeWrapper<ThreadHolderController>()
};
}
}
Note: You probably don't actually intend to have this property be new. Consider making the parent class's property abstract so you can force the child classes to override it.
Another option would be to use Alex Voskresenskiy's approach, with a RegisterType<T>() method, but in that case you probably want that method to be protected, and expect your child class's constructor to call into RegisterType<>() with whatever child types you want to allow. The down-side to this would be that you're doing this work every time the controller is constructed, whereas it's likely you only need it once.
There are likely other, even better, options, like using custom attributes and using a simple unit test to check that all the attributes on all your controllers have the appropriate types in them. But it's hard to say without knowing more about how you intend to use this data.
I'm not sure i got you right, but you can do something like this:
public abstract class CmsAdminController : Controller
{
private Collection<Type> _allowedChildren = new Collection<Type>();
// The type of child controllers allowed
protected Collection<Type> AllowedChildren
{
get {return _allowedChildren; }
}
public void Registertype<T>() where T : IController
{
_allowedChildren.Add(typeof(T));
}
}
The only thing you should also do is to restrict Add on _allowedChildren, for example you can return IEnumerable instead of Collection
Well, I've had to rewrite this as I've been down voted five times for giving too much detail... Go figure!
class BaseModel
{
public T[] Get<T>()
{
// return array of T's
}
public T Find<T>(object param)
{
// return T based on param
}
public T New<T>()
{
// return a new instance of T
}
}
class BaseRow
{
private BaseModel _model;
public BaseRow(SqlDataReader rdr, BaseModel model)
{
// populate properties of inheriting type using rdr column values
}
public void Save()
{
// calls _model.Save(this);
}
}
I currently have a number of classes that inherit the BaseModel class. Each of the methods exposed by BaseModel will return an instance, or an array of instances of a type that inherits the BaseRow class.
At the moment, when calling the exposed methods on the BaseModel via an inheriting class, i.e.
using(DeviceModel model = new DeviceModel())
{
DeviceRow row = model.Find<DeviceRow>(1);
DeviceRow[] rows = model.Get<DeviceRow>();
DeviceRow newRow = model.New<DeviceRow>();
}
I have to specify the type (a class that inherits the BaseRow class), as the methods in BaseModel/BaseRow do not know/care what type they are, other than they inherit from BaseRow.
What I would like to do is find a way to remove the need to specify the without having to replicate code in every class that inherits BaseModel, i.e.
class DeviceModel : BaseModel
{
public DeviceRow Find(object param)
{
return this.Find<DeviceRow>(param);
}
}
Note: Unfortunately I am unable to implement or use any third party solutions. That said, I have tried using Castle Active Record/nHibernate and to be honest, they are very big and heavy for what should be a very simple system.
Hopefully I haven't provided "too much" detail. If I have, please let me know.
Thanks
If I were you, I'd suggest making BaseModel a generic class. In a situation of "can't win either way", the code you've removed to make others happy might have told me more about what you're doing (not a criticism by any stretch - I appreciate your position).
class BaseModel<T>
{
public virtual T[] Get()
{
// return array of T's
}
public virtual T Find(object param)
{
// return T based on param
}
public virtual T New()
{
// return a new instance of T
}
}
That's your base, and then you have inheritors like:
class DeviceModel : BaseModel<Device>
{
public override Device New()
{
return new Device();
}
}
Now, any generic operations you define in DeviceModel will default to returning or using strongly typed Device. Notice the virtual methods in the BaseModel class. In the base class methods, you might provide some basic operations predicated upon using T's or something. In sub-classes, you can define more specific, strongly typed behavior.
I'd also comment that you might want to pull back a little and consider the relationship of BaseModel and BaseRow. It appears that you're defining a parallel inheritance hierarchy, which can tend to be a code smell (this is where more of your code might have come in handy -- I could be wrong about how you're using this). If your ongoing development prospects are that you're going to need to add a FooRow every time you add a FooModel, that's often a bad sign.