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() { }
Related
i got a problem with overwriting a property which comes from an Interface. I got one Base Class which implements an Interface. This class has arround 10 Subclasses. The subclasses should overwrite the property which comes from the Interface in some cases.
My problem is, that i access the property while not knowing what type of class the object has and the object allways returns the base class property value instead of the overwritten subclass property value.
Example Code simplified:
public interface Inf
{
string Info
{
get;
}
}
public class BaseClass : Inf
{
public string Info
{
get { return "Something"; }
}
}
public class SubClass : BaseClass
{
new public string Info
{
get { return "Something else"; }
}
}
in another class i have to access the property, i dont know if the object is type of base or subclass at this moment
List<BaseClass> listBase = new List<BaseClass>();
listBase.Add(new BaseClass());
listBase.Add(new SubClass());
foreach (BaseClass obj in listBase)
{
Console.WriteLine(obj.Info);
}
Output:
Something
Something
wanted output:
Something
Something else
((SubClass)obj).Info would output "Something else"
but at this certain moment i dont know what kind of class the object is. (i have arround 10 different subclasses).
Do i have to cast all objects to it's real class? i got like 100-200 objects in this list and arround 10 different classes. Or is there any other way to do this?
any help appreciated :)
You should make the property implementation virtual in the base class, and put override instead of new on the implementations in derived classes. This should fix the problem.
Currently, the only class that provides the implementation for the property Info from the interface Inf is your BaseClass. According to your code, compiler thinks that the derived class SubClass introduces a new property with the same name, which is legal. Such property would be accessible only when you use the class directly, not through an interface.
You have broken the chain by "new"ing the property. You need to override it:
public interface Inf
{
string Info
{
get;
}
}
public class BaseClass : Inf
{
public virtual string Info
{
get { return "Something"; }
}
}
public class SubClass : BaseClass
{
public override string Info
{
get { return "Something else"; }
}
}
You're doing it wrong. Do following:
declare base class property using virtual keyword
add override keyword next to subclass property declaration
public class BaseClass : Inf
{
public virtual string Info
{
get { return "Something"; }
}
}
public class SubClass : BaseClass
{
public override string Info
{
get { return "Something else"; }
}
}
With that the result is as you expect.
Read more about overriding and polymorphism here: Polymorphism (C# Programming Guide)
I have used and learned only virtual methods of the base class without any knowledge of virtual properties used as
class A
{
public virtual ICollection<B> prop{get;set;}
}
Could someone tell me what that means ?
public virtual ICollection<B> Prop { get; set; }
Translates almost directly to:
private ICollection<B> m_Prop;
public virtual ICollection<B> get_Prop()
{
return m_Prop;
}
public virtual void set_Prop(ICollection<B> value)
{
m_Prop = value;
}
Thus, the virtual keyword allows you to override the property in sub-classes just as you would the above get/set methods:
public override ICollection<B> Prop
{
get { return null; }
set { }
}
In object-oriented programming, a virtual property is a property whose behavior can be overridden within an inheriting class. This concept is an important part of the polymorphism portion of object-oriented programming (OOP).
look at the example below:
public class BaseClass
{
public int Id { get; set; }
public virtual string Name { get; set; }
}
public class DerivedClass : BaseClass
{
public override string Name
{
get
{
return base.Name;
}
set
{
base.Name = "test";
}
}
}
at the presentation level:
DerivedClass instance = new DerivedClass() { Id = 2, Name = "behnoud" };
Console.WriteLine(instance.Name);
Console.ReadKey();
the output will be "test", and not "behnoud", because the "Name" property has been overridden in the derived class(sub class).
In Entity Framework (which I believe your example refers to), your POCO classes are created and wrapped into a proxy class. Proxy class is a descendant of the class that you declare, so your class A becomes a base class. This proxy class is populated with data and returned back to you. This is necessary in order to track changes. Have a look at this article http://technet.microsoft.com/en-us/query/dd456848
I had a similar problem in trying to understand this and after a few debugging sessions and seeing the proxy classes and reading about tracking changes it made be figure out why it is declared the way it is.
Properties are actually specials cases of Getter and Setter methods. So they are like combinations of Getter and Setter methods as shown below:
private string _name;
public string GetName()
{
return _name;
}
public void SetName(string value)
{
this._name = value;
}
So virtual keyword is same for properties as well which means it is overrideable by the child classes and initial implementation can be changed.
Properties are a shortened form of accessor methods (Get & Set). That means that the virtual keyword has the same meaning as with any other method. That means you can override it in derived classes.
You can have methods (often), properties, indexers or events, the virtual keyword has the same meaning : modifying the meaning (override) of the base class item.
With properties, you can change the get/set accessors.
It's a collection that's implementation can vary in a descendant class.
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.
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...
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);
}
}