So I currently have an address book program (purposely basic as didn't fancy writing anything more fancy) so a module of an assessment being done (this is not school work).
I have to demonstrate polymorphism, encapsulation and inheritance in this module.
I was wondering if implementing IEnumerable counts as polymorphism as shown below?
public class AddressBookEnumerator : IEnumerator
{
#region IEnumerable Implementation
public Person[] Contacts;
int Position = -1;
public AddressBookEnumerator(Person[] ContactList)
{
Contacts = ContactList;
}
public bool MoveNext()
{
Position++;
return (Position < Contacts.Length);
}
public void Reset()
{
Position = -1;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public Person Current
{
get
{
try
{
return Contacts[Position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
#endregion
}
I only wonder if it is because of inheriting the IEnumerator class and then creating new methods with different behaviour in for my specific class? Or am I just misunderstanding how IEnumerator works.
I'll try to break it down quickly,
interface IOrganism
{
string GetSpecies();
}
abstract class Animal : IOrganism
{
abstract string GetSpecies();
}
class Rat : Animal
{
public virtual string GetSpecies()
{
return "Ratus";
}
}
sealed class BlackRat : Rat
{
public override string GetSpecies()
{
return string.Format("{0} Ratus", base.GetSpecies()));
}
}
Animal, Rat and BlackRat are all polymorphic with IOrganism. Rat and BlackRat are polymorphic with Animal. Lastly, BlackRat is polymorphic with Rat.
This means, I can write a function,
void OutputSpecies(IOrganism organism)
{
Console.WriteLine(organism.GetSpecies());
}
It can accept any implementor of IOrganism, whether that be Rat, BlackRat or some future implementor, becuase they are all polymorphic with IOrganism.
So, to answer the original question, implementing an interface, like IEnumerable and using it as an argument to a function is using polymorphism. However, your code just implements IEnumerator, so is kind of half way there. It shows the potential for polymorphism but not polymorphism in practice.
Additionally, using IEnumerator as an example may distract from the desired task and you might be better to keep your example more abstract.
Polymorphism is a
a programming language feature that allows values of different data
types to be handled using a uniform interface.
In current code provided I see only one datatype you operate on.
Implementing IEnumerable is about subscribing to contract of a given interface, so your type can be threat like that interface. I, personally, would not dimonstrate this code like polymorphism example.
Whilst you can consider treating types at interface level as polymorphism, for the more academic approach, they are probably thinking more along these kind of lines?
Here we see:
Inheritance from the abstract base class Employee
Encapsulation / Polymorphism when we refer to the GetBonusMultiplier method. We are able to refer to the method from the abstract base class and we are also unaware of the internals of how each type determines the base multiplier. All we know / care is that when we call the method, we get an int value back.
If you wanted to change Employee to an interface IEmployee it would be simple. I would probably still have some kind of abstract base to capture the common fields though so you don't have to reimplement in each class that implements IEmployee.
class Program
{
static void Main(string[] args)
{
var employees = new List<Employee>
{
new Manager(1, "Dave Smith"),
new Director(2, "Peter Thompson")
};
foreach (Employee employee in employees)
{
Console.WriteLine(string.Format("Employee ID: {0}. Employee Name: {1}. Bonus Multiplier: {2}.", employee.Id, employee.Name, employee.GetBonusMultiplier()));
}
Console.ReadKey();
}
}
abstract class Employee
{
public int Id { get; protected set; }
public string Name { get; protected set; }
public abstract int GetBonusMultiplier();
}
class Director : Employee
{
public Director(int employeeId, string name)
{
Id = employeeId;
Name = name;
}
public override int GetBonusMultiplier()
{
return 3;
}
}
class Manager : Employee
{
public Manager(int employeeId, string name)
{
Id = employeeId;
Name = name;
}
public override int GetBonusMultiplier()
{
return 2;
}
}
Related
I've spent hours trying to find a way to implement this and so far I haven't found a good solution, so I'm hoping someone could please help point me in the right direction.
I currently have a C# Winforms project that has an abstract base class with several child classes. Most of the methods are the same but each child class has a few additional methods specific to it.
I want to be able to declare a type of the class being used once and pass that type to all my other methods without having to manually check the type everywhere by going "If Class Type=A Do This Else If Class Type=B Do That, and so on".
The problem is that I need to pass the base class or interface to accomplish this. However, by doing so it means I can no longer access the properties or methods specific to the child classes and I don't know how to fix/workaround this.
Here's a simplified example of what I'm trying to do:
Interface and Class Structure
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Eat();
}
public abstract class Animal : IAnimal
{
public abstract string NameOfAnimal { get; set; }
public abstract void Eat();
}
public class Bird : Animal
{
public Bird()
{
NameOfAnimal = "Bob the Bird";
NumberOfFeathers = 100;
}
// Interface members
public override string NameOfAnimal { get; set; }
public override void Eat()
{
System.Windows.Forms.MessageBox.Show("Eating like a Bird");
}
// Bird specific properties and methods
public int NumberOfFeathers { get; protected set; }
public string SomeOtherBirdSpecificProperty { get; protected set; }
public void Fly()
{
// Fly like a bird
}
}
public class Fish : Animal
{
public Fish()
{
NameOfAnimal = "Jill the Fish";
DoesFishHaveSharpTeeth = true;
}
// Interface members
public override string NameOfAnimal { get; set; }
public override void Eat()
{
System.Windows.Forms.MessageBox.Show("Eating like a Fish");
}
// Fish specific properties
public bool DoesFishHaveSharpTeeth { get; protected set; }
public string SomeOtherFishSpecificProperty { get; protected set; }
}
Main Form Code
private void button1_Click(object sender, EventArgs e)
{
IAnimal myCustomAnimal = null;
string animalTheUserSelected = "Bird";
// Only want to manually specify this once
switch (animalTheUserSelected)
{
case "Bird":
myCustomAnimal = new Bird();
break;
case "Fish":
myCustomAnimal = new Fish();
break;
default:
break;
}
DoSomethingWithACustomAnimal(myCustomAnimal);
}
private void DoSomethingWithACustomAnimal(IAnimal myAnimal)
{
// This works fine
MessageBox.Show(myAnimal.NameOfAnimal);
myAnimal.Eat();
// This doesn't work
MessageBox.Show(myAnimal.NumberOfFeathers);
myAnimal.Fly();
}
I understand why I'm having that issue in the main form code... the compiler doesn't know which type of animal is being passed to it yet so it doesn't know what to show. However, I don't know what I should do to fix this.
I've tried:
Putting all the animal-specific properties in the interface. This works but violates several OOP principles. A fish doesn't have feathers, etc. so these specific properties don't belong there.
Manually checking the type everywhere by going something like "If Type=Fish do abc Else If Type=Bird do def". This also works but violates the DRY principle because I'm repeating myself everywhere. Also with a lot of methods using animals, this will be a nightmare to maintain in the future.
Explicitly casting IAnimal to a specific animal like ((Bird)myCustomAnimal).NumberOfFeathers. This also works but I don't know what cast to use at compile-time. This won't be known until the user selects an animal at run-time.
So I'm just wondering how I can solve this issue?
More specifically, I'm wondering how I can re-design the above code so that I can both:
A) Explicitly declare a type of animal only once and pass that type everywhere (without having to do lots of manual checks in every method to see what type it is before doing something with it)
and also
B) Somehow still have a way to manually access the animal-specific properties like someBird.NumberOfFeathers when I need to.
Any ideas?
It really depends on exactly what you are trying to do and what you are hoping to achieve. All the things you've tried so far are possible approaches, but without more context it's hard to give a general answer. It depends on what the right level of abstraction is for what you are trying to do.
One thing to remember is that you can have a class implement as many interfaces as you need. So you could do something like:
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Eat();
}
public interface IFly
{
void Fly();
}
public interface IHaveFeathers
{
int NumberOfFeathers { get; set; }
}
Then you Bird class can be:
public Bird : Animal, IFly, IHaveFeathers
{
// implementation
}
And now in a method you can do something like:
private void DoSomethingWithACustomAnimal(IAnimal myAnimal)
{
// This works fine
MessageBox.Show(myAnimal.NameOfAnimal);
myAnimal.Eat();
var feathered = myAnimal as IHaveFeathers;
if (feathered != null)
{
MessageBox.Show(feathered.NumberOfFeathers);
}
var flier = myAnimal as IFly;
if (flier != null)
{
flier.Fly();
}
}
The other thing to think about is how to abstract what you need to a higher level. So you need to Fly, but why? What happens with the Animal that can't fly? By Fly are you really just trying to Move? Then perhaps you could do:
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Eat();
void Move();
}
And in your Bird you can do this:
public Bird : Animal, IFly, IHaveFeathers
{
public override void Move()
{
Fly();
}
public void Fly()
{
// your flying implementation
}
// rest of the implementation...
}
One solution would be to use the visitor pattern to define the operations you want to perform on your animal instances.
First you would define a visitor interface which provides a method for each type of animal you have in your hierarchy.
public interface IAnimalVisitor
{
void VisitBird(Bird bird);
void VisitFish(Fish fish);
}
And then you would need to modify your animal classes and interfaces to include a method which accepts a visitor, like so:
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Accept(IAnimalVisitor visitor);
}
Your actual animal classes now look something like this:
public class Bird : IAnimal
{
public Bird()
{
NameOfAnimal = "Bob the Bird";
NumberOfFeathers = 100;
}
public string NameOfAnimal { get; set; }
public int NumberOfFeathers { get; protected set; }
public void Accept (IAnimalVisitor visitor)
{
visitor.VisitBird(this);
}
}
public class Fish : IAnimal
{
public Fish()
{
NameOfAnimal = "Jill the Fish";
DoesFishHaveSharpTeeth = true;
}
public string NameOfAnimal { get; set; }
public bool DoesFishHaveSharpTeeth { get; protected set; }
public void Accept (IAnimalVisitor visitor)
{
visitor.VisitFish(this);
}
}
Now for anything you want to do with each of your animals you will need to define an implementation of the IAnimalVisitor interface. In your example you displayed message boxes that showed information about the animal so an implementation of the IAnimalVisitor interface that does that could look like this:
public class AnimalMessageBoxes : IAnimalVisitor
{
private void VisitAnimal(IAnimal animal)
{
MessageBox.Show(animal.NameOfAnimal);
}
public void VisitBird(Bird bird)
{
visitAnimal(bird);
MessageBox.Show(bird.NumberOfFeathers);
}
public void VisitFish(Fish fish)
{
visitAnimal(fish);
MessageBox.Show(fish.DoesFishHaveSharpTeeth);
}
}
Now you just need to pass your visitor to your animal and the correct information will be displayed. Your event handling code now looks something like this:
string animalTheUserSelected = "Bird";
IAnimal myCustomAnimal = null;
switch (animalTheUserSelected)
{
case "Bird":
myCustomAnimal = new Bird();
break;
case "Fish":
myCustomAnimal = new Fish();
break;
default:
break;
}
AnimalMessageBoxes msgBoxes = new AnimalMessageBoxes();
myCustomAnimal.Accept(msgBoxes);
If you want to do something else to your animal instances (save them to a file, generate a UI, play sounds...) you just need to define a new IAnimalVisitor implementation that provides your desired behaviour.
For the sake of balance I will say that this might not be an appropriate design as it adds some additional complexity; each 'operation' requires you to implement a visitor and the addition of another animal to your hierarchy requires you to update your visitor interface and all of it's implementations to account for the new case.
Depending on your point of view this can be either good or bad. Some consider the points above to be bad and a reason to avoid the visitor pattern and to use the other methods already suggested. Others (like me) consider the points above to be a good thing; your code will now only compile when you provide an implementation for each animal in your hierarchy and your operations are separated into small, dedicated classes.
My suggestion would be to try the SSCCE I have provided and research the visitor pattern further to decide if this solution is acceptable for your requirements.
I understand, what you are trying to achive, but your approach is just wrong.
Think it this way: does your "Main" class/form realy need to know if there is a bird or a dog? The answer is "NO". There are some common properties which you exposed via an interface (i suggest using a base class here!). Everything else is specific to the given animal. The easiest approach is extending your interface with a DoAnimalSpecificStuff() method - which would perform the specific opperations.
When it comes to presentation, you should take a look at the MVP and MVVM Patterns.
P.S. use a Factory Pattern for animal creation!
You have to explicitly cast the IAnimal object to specific type, if you want to access specific properties/methods.
You can use as operator and then check if the cast was successful like:
Bird b = myAnimal as Bird;
if(b != null)
{
MessageBox.Show(b.NumberOfFeathers);
}
I have a interface with constraint as a Base class
abstract class BaseElement { };
interface IOperation <T>where T:BaseElement
{
void Add (T field1);
}
Created a child object for the Base class
class StudentDTO : BaseElement
{
public int Id { get; set; }
};
class SubjectDTO : BaseElement
{
public string Name { get; set; }
};
Implemented 2 classes with IOperation interface
class Student : IOperation<StudentDTO>
{
public void Add(StudentDTO field1)
{
Console.WriteLine("Child A" + field1.Id);
}
}
class Subject : IOperation<SubjectDTO>
{
public void Add(SubjectDTO field1)
{
Console.WriteLine("Child B" + field1.Name);
}
}
Implemented a factory pattern to return the DTO objects.
static class BLFactory
{
public static IOperation<BaseElement> CreateObject(BaseElement baseObject)
{
if (baseObject.GetType().Name == "SubjectDTO")
{
return new StudentDTO() as IOperation<BaseElement>;
}
else
{
var temp = new SubjectDTO() as IOperation<BaseElement>;
return temp;
////************ temp object returns null *************
}
}
}
Now, when I use the BLFactory to create the DTO objects, I am getting it as NULL. Not sure how to fix the problem.
Any advice how to fix this or what is the right way of implementing.
Well, first off StudentDTO doesn't implement IOperation at all; Student does, but StudentDTO doesn't.
And even if you did use Student that wouldn't work either. Student implements IOperation<StudentDTO> not IOperation<BaseElement>.
Just because StudentDTO can be implicitly converted to BaseElement does not mean that IOperation<StudentDTO> can be implicitly converted to IOperation<BaseElement>. IOperation would need to be covariant for that to be the case, and it's not.
If you wanted, you could make IOperation contravariant, given that T is only used as input, but that would then enable you to implicitly convert an IOperation<BaseElement> to an IOperation<StudentDTO>, not the reverse.
According to documentation of as operator:
The as operator is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception.
As StudentDTO is not inherited from IOperation<...> and SubjectDTO is not inherited from IOperation<...> you will get null in temp variable as result of as operatior.
Because SubjectDTO is NOT an IOperation<BaseElement>. It is a BaseElement.
Neither is a Subject - it is an IOperation<SubjectDTO> which does NOT inherit from IOperation<BaseElement>.
It seems like your BLFactory is basically returning the proper "repository" for each type, which may be better done declaratively using a DI framework like Ninject or Unity.
However, if you want to hard-code it, you could make BLFactory generic:
static class BLFactory<U> where U:BaseElement
{
public static IOperation<U> CreateObject()
{
if (typeof(U).Name == "SubjectDTO")
{
return new Student() as IOperation<U>;
}
else
{
return new Subject() as IOperation<U>;
}
}
}
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);
}
}
(C#, VS2008) In a program I'm working on, I've got lots of objects that all have an ID and implement IComparable so that List<>-s of the various objects are easily searchable by ID. Since I hate copy/pasting code, I thought I'd abstract that bit of functionality down to a base class, like so:
using System;
namespace MyProg.Logic
{
abstract class IDObject : IComparable<IDObject>
{
private int miID;
public int ID
{
get { return miID; }
set { miID = value; }
}
public IDObject(int ID)
{
miID = ID;
}
#region IComparable<IDObject> Members
int IComparable<IDObject>.CompareTo(IDObject other)
{
return miID.CompareTo(other.miID);
}
#endregion
}
}
The drawback I see to that is that two separate classes that each inherit it would be directly comparable using .CompareTo() and I was hoping to enforce that each class that inherits from IDObject is only Comparable to others of the exact same class. So I was hoping to figure out how to do that and came up with this
using System;
namespace MyProg.Logic
{
abstract class IDObject : IComparable<T> where T : IDObject
{
private int miID;
public int ID
{
get { return miID; }
set { miID = value; }
}
public IDObject(int ID)
{
miID = ID;
}
#region IComparable<T> Members
int IComparable<T>.CompareTo(T other)
{
return miID.CompareTo(other.miID);
}
#endregion
}
}
But that gives a compile error of "Constraints are not allowed on non-generic declarations"
Looking at it, I'm sure there's a way to do something like that so that each class is only comparable to other instances of that same class, but I can't tease out the syntax.
You can use the Curiously Recurring Template Pattern to solve this problem.
abstract class Base<T> : IComparable<T> where T : Base<T> {
public int Rank { get; set; } // Order instances of derived type T by Rank
public int CompareTo(T other) { return Rank.CompareTo(other.Rank); }
}
class Foo : Base<Foo> {}
class Bar : Base<Bar> {}
static class Program {
static void Main() {
var foo1 = new Foo { Rank = 1 };
var foo2 = new Foo { Rank = 2 };
var bar1 = new Bar { Rank = 1 };
var bar2 = new Bar { Rank = 2 };
Console.WriteLine(foo1.CompareTo(foo2));
Console.WriteLine(bar2.CompareTo(bar1));
//error CS1503: Argument '1': cannot convert from 'Bar' to 'Foo'
//Console.WriteLine(foo1.CompareTo(bar1));
}
}
I think you've got bigger problems than just making sure that the derived class types are the same. You are also saddling the derived class with the responsibility to generate a unique ID. That requires the derived class to be aware what other IDs were assigned previously. Realistically, that requires a class factory. You'll need to enforce that by making the constructor of your abstract class protected.
Not very practical. If the ID is just an opaque number that establishes object identity then consider assigning the ID yourself. Use a static member to keep track of the last assigned one. Now it becomes simple, and you don't have to worry about derived class types anymore.