Class Design - Base class with Generic Descendant - c#

I have the following classes
class GridBase
{
public object DataSource { get; set; }
}
class GenericGrid<T> : GridBase
{
public new T DataSource { get; set; }
}
Both GridBase and Generic Grid classes can be instantiated and one can descend from either as well.
Is this considered the correct/accepted way to implement such a hierarchy?
Or should you go the extra mile and implement it like the following
class GridBase
{
protected object dataSource;
public object DataSource { get { return dataSource; } set { dataSource = value; } }
}
class GenericGrid<T> : GridBase
{
public new T DataSource { get { return (T)dataSource; } set { dataSource = value; } }
}
The same applies to non generic classes when a property is re-introduced in a descendant, I'm just using a generic example here.
Another case and question
abstract class SomeBase
{
protected abstract void DoSomething();
}
class Child : SomeBase
{
protected override void DoSomething()
{
/* Some implementation here */
}
}
The situation here is that framework "X" declares SomeBase allowing you to define your own descendants. The classes they create (at run time) then descend from your class (Child in the this case). However, they don't call your DoSomething() method, from their implementation of DoSomething().
On their part, they can't blindly call base.Dosomething() either because the typical case is that the class they generate normally descends from SomeBase and since the method is abstract that's not valid. (Personally, I don't like this behavior in C#).
But anyway, is that good or accepted design, that is not calling base.xxx(), especially when the the "intent" seems to contradict?
EDIT From a framework design perspective. Is it ok/acceptable that it does this? If not how would it be designed so as to either prevent such a case or better impart their intent (in both cases).

I would prefer something like this:
interface IGrid {
object DataSource { get; }
}
interface IGrid<T> {
T DataSource { get; }
}
public Grid : IGrid {
public object DataSource { get; private set; }
// details elided
}
public Grid<T> : IGrid<T> {
public T DataSource { get; private set; }
object IGrid.DataSource { get { return this.DataSource; } }
// details elided
}
Note that I am NOT inheriting from Grid.

For the DataSource question I prefer the following pattern
abstract class GridBase {
public abstract object DataSource { get; }
}
class GenericGrid<T> : GridBase {
private T m_data;
public override object DataSource {
get { return m_data; }
}
public T DataSourceTyped {
get { return m_data; }
set { m_data = value; }
}
}
Reasons
Having the GridBase.DataSource member be writable is type unsafe. It allows me to break the contract of GenericGrid<T> by setting the value to a non-T instance
This is more of a matter of opinion but I dislike the use of new because it often confuses users. I prefer the suffix ~Type" for this scenario
This only requires the data be stored once
Doesn't require any unsafe casting.
EDIT OP corrected that GridBase and GenericGrid are both usable types
In that case I would say you need to reconsider your design a bit. Having them both as usable types opens you up to very easy to expose type errors.
GenericGrid<int> grid = new GenericGrid<int>();
GridBase baseGrid = grid;
baseGrid.DataSource = "bad";
Console.Write(grid.DataSource); // Error!!!
The design will be a lot more reliable if separate the storage from the access of the values in a manner like my original sample. You could extend it further with the following code to have a usable non-generic container
class Grid : GridBase {
private objecm m_data;
public override object DataSource {
get { return m_data; }
}
public object DataSourceTyped {
get { return m_data; }
set { m_data = value; }
}
}

The second form of the generic inheritance (casting the base class' attribute) is more correct as it does not violate Liskov Substitution Principle. It is conceivable that an instance of the generic class is cast into base class and accessing Data through the base class points to a different property. You will need to keep both in sync in order for the derived class to be substitutable for the base class.
Alternatively, you can implement some sort of a strategy pattern where the base class asks for the Data property from the derived class, in order to avoid awkward downcasting. This is what I had in mind:
public class Base {
private readonly object m_Data; //immutable data, as per JaredPar suggestion that base class shouldn't be able to change it
publlic Base(object data) {
m_Data = data;
}
protected virtual object GetData() {return m_Data;}
public Object DataSource {get {return GetData();}}
}
public class Derived<T> : Base {
private T m_Data;
public Derived():base(null){}
protected override object GetData() {return m_Data;}
protected new T Data {return m_Data;}
}
With regards to the second question, I am note sure I understand the question. Sound like the problem you are having is to with the framework not calling the abstract method when it generates a proxy at runtime, which is always legal in abstract classes, as the only way for that code to execute is through a derived class which must override the abstract method.

Related

Can an interface require a property, but not specify a required type?

I have a simple interface, defined as such:
interface iFace
{
int Value { get; }
}
In this case, any class implementing iFace must have a property named Value of type int. The usage of this interface is going to be with databinding, and I don't care what type the property is. Do I have any options? I'd like to avoid this solution:
interface iFace<T>
{
T Value { get; }
}
as I'd like to refer to the interface without specifying type
Edit:
I'd like to be able able to apply the same interface to both a NumericUpDown control, and a Trackbar control. One's value property is of type decimal, and the other is of type int.
Having the property be of type object wouldn't work in this case.
If you don't care whether it is strictly-typed, change the property type to object.
Try this:
interface MyInterface
{
Object MyProperty
{
get;
set;
}
}
class MyClass : MyInterface
{
Object MyInterface.MyProperty
{
get
{
return this.MyProperty;
}
set
{
if (value is MyType)
this.MyProperty = (MyType)value;
}
}
public MyType MyProperty
{
get;
set;
}
}
In response to your edit: You're coming up against the well-known problem that .NET has no INumeric interface. It exists in source code I've seen, but it has been commented out, which implies that Microsoft has taken it seriously enough and run into some significant issues with it.
Danny Varod's solution is a good one; you can also extend it by creating a generic and a non-generic version of the interface. Another solution is to add methods to the interface that represent the numeric operations for which you're now using mathematical operators, like Increment(), for example.
I'll call the interface IHasValue here (partly because it is somewhat comedic):
interface IHasValue
{
object Value { get; set; }
void Increment();
void Decrement();
}
interface IHasValue<TValue> : IHasValue { new TValue Value { get; set; } }
abstract class UpDownValueControl<T> : IHasValue<T>
{
public T Value { get; set; }
object IHasValue.Value
{
get { return this.Value; }
set { this.Value = (T)value; }
}
public abstract void Increment();
public abstract void Decrement();
}
class NumericUpDownControl : UpDownValueControl<decimal>
{
public override void Increment() { Value++; }
public override void Decrement() { Value--; }
//rest of the implementation
}
class TrackbarControl : UpDownValueControl<int>
{
public override void Increment() { Value++; }
public override void Decrement() { Value--; }
//rest of the implementation
}
It's frustrating that the base class can't take care of repetitive code like the increment and decrement methods, but at least this approach allows the base class to take care of everything else aside from the repetitive mathematical operator code.
I suspect, in the end, that the complexity of this solution adds more cost than benefit; I think I'd be more likely to go with something like Danny Varod's solution.

Decorator pattern wasting memory

I have this base class having the following interface:
abstract class Base
{
abstract public object Val
{
get;
}
}
For any derived classes, Val's value must be specified at object creation time.
The question is: How can I make a derived class do this (hopefully at compile time)?
I tried adding a constructor:
abstract class Base
{
public Base(object value)
{
val = value;
}
private object val;
...
}
But as you can see then I had to declare a private field to store value in it (because Value is read-only).
The problem arises because I want to add some kind of effect to derived classes using the Decorator/Wrapper pattern introduced in GoF Design Patterns. But because I have declared the field inside Base class, the decorators keep saving a copy of the same data and I end up wasting memory.
Try this instead:
abstract class Base
{
public Base(object val)
{
this.Val = val;
}
public object Val { get; private set; }
}
That way, your derived class doesn't need its own field:
public class Derived : Base
{
public Derived(object val) : base(val) { }
}
If it is a decorator, then don't have a field:
public override object Val {
// add any decoration effects here if needed
get { return tail.Val; }
}
Where tail is the thing you are decorating.
However, it sounds like you mean inheritance (not decoration) - if so:
abstract class BaseClass {
protected BaseClass(object val) {...}
}
class ConcreteType : BaseClass {
public ConcreteType(object val)
: base(val) { }
}
Here the base class could even handle the storage etc.

Abstract classes and accessors

Main Question:
I have a reference type (object/class) where I would like to specify accessors' implementation details, but I don't want the type to be instantiable, only extendible.
Abstract Classes don't allow bodies to the accessors of Properties as far as I understand, so that makes it trouble some for me.
How would I go about this in the most 'correct' and elegant manner?
Second question:
I would also like functionality for overloading accessors if there is a way? One reason is that I have an enum Property, which I want to be settable by using its value (int) or its enum reference type.
Abstract Classes don't allow bodies to the accessors of Properties as far as I understand
Yes they do... this is perfectly legal
abstract class MyBaseClass
{
private int _myProperty;
public int MyProperty
{
get { return _myProperty; }
set { _myProperty = value; }
}
}
Perhaps you're confusing abstract classes and interfaces; interfaces can declare members, but they can't provide an implementation for those members.
Abstract Classes don't allow bodies to the accessors of Properties as
far as I understand, so that makes it trouble some for me.
yes they do;
public abstract class Foo
{
public string Prop
{
get { return "yesTheyDo"; }
}
}
are you marking them abstract?
I think this should do what you want:
public abstract class MyParentClass
{
public enum MyEnum
{
one,
two,
three
}
private MyEnum _enumeration;
public string Name { get; private set; }
public MyEnum Enumeration { get { return this._enumeration; } }
public void SetEnumeration(string value)
{
// ... do something
}
public void SetEnumeration(MyEnum value)
{
// ... do something
}
}
There are two overloaded methods for setting the Enumeration property and some methods have their bodies declared whilst the whole class cannot be instantiated.
Hope that helps :)
You can define the body of methods and properties inside of an abstract class. The abstract part of it essentially just prevents it from being instantiated. To accomplish this, you would write the property as normal:
public string Name
{
get { return "SomeName"; }
}
As an example. As for allowing overloading of accessors, you could do one of the following:
// By setting this as 'virtual' you can allow classes that inherit from this to override the functionality if they so wish
public virtual string Name
{
get { return "SomeName"; }
}
// or
public virtual string GetName()
{
return "SomeName";
}
One tip: if you are wanting the functionality to be overridden and accessible only to classes that inherit the abstract class, use the protected keyword:
protected virtual void DoSomething() { }

Correct to use an implementation instead of the abstraction or change implementation?

I have a situation where I have 2 Activity objects (let's say empty and scheduled activity, not controlled by me) that share a couple of behaviors, like the person who booked the activity, the room where that activity takes place, activity type, subject etc.
I created two wrappers objects (EmptyWrapper and ScheduledWrapper) that have a super class ActivityWrapper that implements some methods common to both childs and has some abstract methods/properties for the child wrappers to respond accordingly. They are very much alike in behavior but there is one crucial difference, you can only schedule activities if it is an empty slot! The structure is something like this (very simplified code):
public class EmptyWrapper : AppWrapper
{
EmptySlot _emptySlot;
public EmptySlotWrapper(EmptySlot emptySlot) : base()
{
this._emptySlot = emptySlot;
}
public override string Id
{
get { return _emptySlot.AgendaId; }
}
public override string Room;
{
get{ return _emptySlot.Room;}
}
public override string Person
{
get{ return _emptySlot.Person;}
}
public override string AppType;
{
get{ return "Empty";}
}
public override bool IsAppSlot()
{
return false;
}
public override bool IsEmptySlot()
{
return true;
}
public override bool CanPerformOperations()
{
return true;
}
public void ReserveApp(ObjWithActivityInfo actObj)
{
(...)
}
}
The ActivityWrapper is similar but the object wrapped around is different, the bools return true for IsAppSlot, false for IsEmptySlot and false for CanPerformOperations and there is no ReserveApp() method.
Next is the base class:
public abstract class AppWrapper
{
public abstract string Collaborator { get; }
public abstract string Room { get; }
public abstract string AppType { get;}
public AppWrapper()
{ }
public abstract bool IsAppSlot();
public abstract bool IsEmptySlot();
public abstract bool CanPerformOperations();
public virtual string GetTextToShow()
{
return Person + " - " + Room;
}
(...)
}
In my code I wanted to reference only the ActivityWrapper, because for the general operations (show the info and appearance) I don't need the implementations. The problem rises when I need to book activities for empty slots. In that point, in my code, I cast the AppointmentWrapper to the EmptyWrapper and reserve the slot for the activity (it is still an EmptySlot but it's reserved to the selected activity), otherwise, if the cast was unsucessful I don't do anything because it was not the correct Activity Type.
Is this correct, or should I implement the ReserveActivity() method in both wrappers and have the ActivityWrapper do nothing?
Or should I do this in another way? Maybe to alter the structure of the classes?
Sorry for the long text.
There is no point in adding a function to a class that does not require it. It would defeat the point of your inheritance.
I'd do a safe cast ...
var i = obj as theClass
and then test for null. I'd use a bit of linq to select all o the objects that have the property you defined to indicate what type they are set to true.
You could do it the other way and save yourself the cast and test, but it means the design is less obvious to an outsider.
I think its a matter of taste but prefer the way you did it. I am not sure i like the bool properties to identify the type though. What if you inherit off the base class again? Besides you can cast to identify the type - which with a deeper object structure may be more useful.
I agree with your desire to work with a collection of the abstract class though.
In the several occasions that I had to deal with a similiar problem, I tend to think that it's really more elegant to create Interfaces for recognizing common functionailty for several objects then to create abstract methods which the inheriting classes will implement the way you mentioned.
e.g.
public interface IAppSlotContainer
{
void relevant_Method_When_ObjectIsAppSlot();
}
public interface IEmptySlotContainer
{
void relevant_Method_When_ObjectIsEmptySlot();
}
public class EmptyWrapper : AppWrapper, IAppSlotContainer, IEmptySlotContainer
{
public EmptyWrapper(EmptySlot emptySlot) : base()
{
this._emptySlot = emptySlot;
}
public override string Id
{
get { return _emptySlot.AgendaId; }
}
public void relevant_Method_When_ObjectIsEmptySlot()
{
}
public void relevant_Method_When_ObjectIsAppSlot()
{
}
}
Then instead of overwriting the abstract method "IsEmpty" and implementing it as "return true", just check whether the object is an instance of IEmptySlotContainer, cast it to that interface, and execute the interface related command.
it is far more generic and elegant for my taste...
Hope this helps...

Creating read-only versions of classes in a complex object structure

In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}

Categories