I am building an application where the datamodel is fixed, but people (or just me) can extend it by adding classes that inherit from the base class that gets instantiated from the info in the db and serialized in services.
I have three problem areas with this (case 1 2 and 3 in the sample code below).
Case #1 I could maybe solve with an interface, but that doesn't help me with case 2 or 3.
I think the code sample will speak better than my attempts to explain; any idead on how to approach this so that each new field type doesn't need to get manually added to a bunch of places in the code?
public class ManagerClass
{
public ManagerClass()
{
public ManagerClass()
{
}
//Case #1
public void process(AllFields allFields)
{
foreach (Field field in allFields.Fields)
{
//Currently I need to add all extention types as seperate cases here manually
//...this type of logic appears in several places in the code
if (field.GetType().Name == "ExtendedField")
{
//Have the extended field do something in a way particular to it
}
else
{
//Have the base field do something the "normal" way
}
}
}
//Case #2
//Here is another case where currently I am adding each case in by hand
//fieldType is a string here because I am storing what type of field it is in the DB
public void create(string value, string fieldType)
{
//Currently I need to add all extention types as seperate cases here manually
if (fieldType == "ExtendedField")
{
//Create a ExtendedField
}
else
{
//Create a Field
}
}
}
}
[DataContract]
//Case #3
[KnownType(typeof(ExtendedField))] //Currently I need to add all extention types here manually
public class AllFields
{
private List<Field> fields;
public AllFields(){}
[DataMember]
public List<Field> Fields
{
get { return fields; }
set { fields = value; }
}
}
[DataContract]
public class Field
{
private string fieldValue;
public Field(){}
[DataMember]
public string FieldValue
{
get { return fieldValue; }
set { fieldValue = value; }
}
}
[DataContract]
public class ExtendedField : Field
{
private string someOtherAttribute;
public ExtendedField(){}
[DataMember]
public string SomeOtherAttribute
{
get { return someOtherAttribute; }
set { someOtherAttribute = value; }
}
}
Sounds like you're trying to build an miniature extensibility framework. Consider something like this where the extension logic is handled by a FieldHandler:
public class FieldHandler
{
public virtual Field CreateField(string value, string fieldType){...}
}
// Case 2
Field field = null;
foreach (FieldHandler handler in m_handlers)
{
if (handler.SupportsFieldType(fieldType))
{
field = handler.CreateField (value, fieldType);
continue;
}
}
if (field == null)
{
// Create standard field.
field = ...;
}
For extensible Field reading:
Make Field an abstract class, and make all your common methods abstract as well. Classes derived from Field will specify exactly what those methods do.
You can then pass objects of these derived classes back to methods that accept a Field, and they can call the methods of Field without needing to worry about the real class that is being used. Interface would be even better, but you don't get code reuse for common functionality.
For extensible Field creating:
You will always have to do a switch or something somewhere at the boundaries of your program to determine which class to create. Your goal is to do this in only one place. Your design - determining the factory method to use based on data in the DB - is ideal.
Look into making a class that will have the responsibility to create Field objects based on DB data and just pass it around. If it were abstract, you could subclass it and pass it as a parameter to methods, methods that will get the data they want by calling something like fieldFactory.GetNewField(myParameter);.
For extensible serialization:
Research DataContractResolver.
Tips:
If you find yourself having to switch on the type of Field in more than one place (where the constructors are called), you're doing it wrong. An example of this is your process(field) method. Instead, Field or IField should have an abstract Process method. Consumers will just call Field.Process and not care how it is implemented.
Example:
public abstract class Field
{
public abstract void Process();
}
public class ExtendedField : Field
{
public override void Process() { /*Extended Field Specific Stuff Here*/ }
}
//consumer code
public void DoStuffWithABunchOfFieldsOfUnknownType(IEnumerable<Field> fields)
{
foreach (Field field in fields) { field.Process(); }
}
Related
Thanks ahead, community!
As the title describes, I would like to cast an object that is in parent type to a child type, which is actually a child type, whilst this 'specific type' cannot be known until runtime.
Lets say I have following data holder:
public class Holder {}
public class Holder<T> : Holder
{
public T Value;
}
And this Holder (not Holder<T>) will be given to some script at runtime.
I need to cast this Holder into Holder<T> (eg, Holder<string>), so that I can access the Value : T.
For now, I can just mannually add casting cases and their coresponding methods to process it, but time by time there will be more types that goes into this Holder<T>, and it would become imposible to manage in this way.
Is there a way to accomplish this objective?
This Holder must not be flattened, as it is being used in a context as below:
public class SomeNode
{
protected Holder holder;
}
public class SomeNode<T> : SomeNode
{
public SomeNode<T>()
{
holder = new Holder<T>();
}
}
I have no clue how to approach this, nor a search keyword to catch a hint about this.
Automatic suggestions came up before posting seems not my case, which were:
C# Create (or cast) objects of a specific type at runtime
C# Accessing generic Method without knowing specific type
Edit
Thanks to #W.F., I could start searching with an effective keyword 'dynamic object', and I ended up finding System.Reflection as my desired soultion.
It looks like as belows and currently it solves my immediate issue:
holder.GetType().GetProperty("GetValue").Invoke(holder, null);
But as pointed out by #OlivierJacot-Descombes, my structure and a way of using it is breaking a purpose of polymorphism. Therefore I still need a better solution, which would do a job I am looking for and also not breaking polymorphism.
Possible walkaround that comes in my head is that, first, create a method GetValue() in Holder, and also create class that inherits from Holder to implement this method:
public class Holder
{
public virtual string GetValue() => "";
}
public class Holder<T> : Holder
{
public T Value;
}
public class FloatHolder : Holder<float> //for example
{
public override string GetValue() => Value.ToString();
}
Second, change node structure like:
public class SomeNode
{
protected Holder holder;
}
public class SomeNode<T> : SomeNode {}
public class FloatNode : SomeNode<float>
{
public FloatNode()
{
holder = new FloatHolder();
}
}
Then, I can do like:
public class EchoNode : SomeNode
{
public void Tick()
{
Console.WriteLine(holder.GetValue());
}
}
Seems like too many classes are being created, but it also seems not breaking polymorphism.
Looking for further advices. Again, Thanks!
Edit#2
I already said this in the comment, but for better readability, I write this here as well.
Both Dynamic Object and System.Reflection were easy and fitting solutions which I was looking for, but they weren't best solutions in general.
At the beginning I was misinterpreting #OlivierJacot-Descombes 's answer. He was overall pointing out two impediments: first, my class structure is breaking polymorphism, and second, reflection is slow (and later I noticed, dynamic object as well). I didn't catch the last bit at first so I went through a long way.
Moreover, turned out, I couldn't use dynamic object for my project context, as I am not using normal C# but a Unity C#. Technically I can, but they don't blend well.
Thankfully, my revised solution was acceptable. Therefore I decided to select #OlivierJacot-Descombes 's post as an answer. But I hope, still, people would approach and leave me an good advices.
Thank you all.
If you need to cast to a specific type, you are doing polymorphism wrong. Of course you could do something like this:
switch (holder)
{
case Holder<string> stringHolder:
DoStringThing(stringHolder.Value);
break;
case Holder<int> intHolder:
DoIntThing(intHolder.Value);
break;
...
}
See also: Switch statements with patterns.
However, the idea behind polymorphism is to be able to do things without having to know the specific type. Therefore, re-design the holder classes and have them do the type specific thing themselves:
public abstract class Holder
{
public abstract void DoThing();
}
public abstract class Holder<T> : Holder
{
public abstract T Value { get; }
}
Some examples of specific types:
public class StringHolder : Holder<string>
{
public StringHolder(string value)
{
Value = value;
}
public override string Value { get; }
public override void DoThing()
{
Console.WriteLine($"String of length {Value.Length} is \"{Value}\"");
}
}
public class IntHolder : Holder<int>
{
public IntHolder(int value)
{
Value = value;
}
public override int Value { get; }
public override void DoThing()
{
Console.WriteLine($"The integer {Value} is {(Value % 2 == 0 ? "even" : "odd")}");
}
}
Now you can simply write
holder.DoThing();
... without having to cast.
Update
Your edited question indeed shows a polymorphic version.
Here I want to present another approach which merges Holder and Holder<T> in a single class through the use of interfaces.
public interface IHolder
{
object Value { get; set; }
}
public interface IHolder<T> : IHolder
{
new T Value { get; set; } // The new keyword hides the inherited property.
}
public class Holder<T> : IHolder<T>
{
object IHolder.Value
{
get => Value; // Returns T Holder<T>.Value as object.
set => Value = value is T t ? t : default; // Sets T Holder<T>.Value.
}
public T Value { get; set; }
}
Holder<T> now implements a "neutral" Value property declared in IHolder based on the object type. Since it implements it explicitly (i.e., instead of public object Value we write object IHolder.Value), this property is hidden, unless it is accessed through the interface. This allows you, for example, to declare a List<IHolder> and to retrieve different kinds of Holder<T> values with list[i].Value as object.
But you have a variable Holder<float> floatHolder, you can get the strongly typed float value.
Note that this still allows you do derive more specific types like class FloatHolder : Holder<float>, but it might not even be necessary.
If you intend to work only with derived types, you can mark Holder<T> as abstract and also all the members that must be implemented by the deriving classes. This makes it impossible to create an instance of Holder<T> with new and also allows you to declare abstract methods without body.
community! It's a good question. That was interesting.
I think this is simple solve for this question.
We just need to create a simple constructor like below
public class Holder
{
public string SomeData; // just example data
public Holder()
{
}
public Holder(Holder someData)
{
SomeData = someData.SomeData;
}
}
public class Holder<T> : Holder
{
public T Value;
public Holder(Holder a, T t = default)
:base(a)
{
Value = t;
}
}
public class Programm
{
void Main()
{
var h = new Holder();
var g = new Holder<string>(h);
}
}
I am curently working on a small project (C#) where I have data to analyse.
To do so, I pass the data into the constructor of a class.
The class makes a first analysis on the data, and a certain value is determined using the data. Using this value I can say that this data is of Type B, C, D, ... and the analysis would continue in another class corresponding to the data type.
This would be it's class diagram representation :
So the "Data" Class should abstract but not really ? ¯\_(ツ)_/¯
I did some reasearch about the factory design pattern, but I think this is not really what I am trying to achieve. Is there maybe an other design pattern that does what I want to do?
Thank you for helping.
If I understand you correctly, you want the base class to determine which child class to create based on the data passed into the constructor. If so, you can't do it that way - a class cannot change itself to be a different/derived type when being constructed.
I assume that all the data types have some common properties and so you decided to put those common properties in a base class. I also assume you don't want each data type child class to have redundant code setting those common properties in the base class. You accomplish that by having the child class call a method in the base class, passing the data. You can do this in the constructors if you wish. For example:
class BaseData
{
BaseData(Dictionary<string,string> data)
{
this.CommonProp1 = data["CommonProp1"];
this.CommonProp2 = data["CommonProp2"];
}
public string CommonProp1 { get; set; }
public string CommonProp2 { get; set; }
}
class DataTypeA : BaseData
{
DataTypeA(Dictionary<string,string> data)
: base(data) // <-- magic here
{
this.TypeA_Prop1 = data["TypeA_Prop1"];
this.TypeA_Prop2 = data["TypeA_Prop2"];
}
public string TypeA_Prop1 { get; set; }
public string TypeA_Prop2 { get; set; }
}
I believe the factory pattern actually is what you want since you want to create an instance of a class in which the type is determined at run time. This is where you encapsulate the code that determines which type of child class to create. Something like:
class DataFactory
{
public static BaseData BuildDataClass(byte[] serializedData)
{
Dictionary<string,string> data = ParseData(serializedData);
switch (data["DataType"])
{
case "TypeA":
return new DataTypeA(data);
default:
return null;
}
}
private static Dictionary<string,string> ParseData(byte[] serializedData)
{
var data = new Dictionary<string, string>();
// bla bla
return data;
}
}
I would like to be able to pass a known type to a general function but I'm getting compile errors because I can't cast the type at design time.
Consider my OnCreate function:
EXAMPLE 1:
private void OnCreate<T>(T object)
{
object.CurrentDate = DateTime.Now;
object.SpecialProperty = "Hello";
}
EXAMPLE 2:
private void OnCreate<T>(T object)
{
object.BirthDate = DateTime.Now;
object.BirthdayMessage = "Happy Birthday";
}
I want to call OnCreate and pass to it an object. That object happens to be a model object in an MVC application. I can't predict what model object is being passed to OnCreate yet I want to access the unique properties of the model that is passed. As my examples show above, one model has a CurrentDate and a SpecialProperty property; another has a BirthDate and a BirthdayMessage property. I don't want to create a special function for each because I have many different models. Also, this OnCreate function is going to get inherited from a base class. The idea here is to provide a "hook" into the controller's Create method so that someone can alter the model properties before they are persisted to the database. In other words, the controller's Create method would pass the model to my OnCreate function, then some work would be done on the model before it's passed back.
As you would expect, each model has different properties. Due to this requirement, I realize that I won't be able to early-bind and get intellisense with the OnCreate function--but my problem is that the compiler won't let me refer to properties of the object until it knows the object type. I can't cast it at design-time because I don't know the type until run-time.
EDIT
I think my question wasn't so clear, judging by the answers (for which I'm grateful--they're just not what I'm looking for). Perhaps it's better to show how I want to call OnCreate():
OnCreate(model);
Now, when OnCreate receives object "model", it needs to be able to set properties on that model. I suppose I could use reflection on the model and do something like this (this is pseudocode only--still learning about reflection):
if typeof(model) is CustomerModel then
(CustomerModel(model)).BirthDate = "1/1/1960";
(CustomerModel(model)).BirthdayMessage = "Happy Birthday";
elseif typeof(model) is AnotherModel then
(AnotherModel(model)).CurrentDate = DateTime.Now;
(AnotherModel(model)).SpecialProperty = "Hello";
etc...
But I am trying to avoid having a bunch of if/then statements. I prefer if the call could be "routed" to a function that's specific for the type being passed. That way, the call to OnCreate would send the object to an overload(?) so that no reflection logic is needed...
SECOND EDIT
Upon further reflection (no pun intended), I don't think having a bunch of if/else statements in the OnCreate function is the best approach here. I came up with another idea that might work best and accommodates my expressed wish to "avoid having a bunch of if/then statements" (specified in my first Edit): The idea is to have my models implement IOnCreate, which would provide the .OnCreate() method. Thus, my "generic" model objects that implement IOnCreate could be used this way:
model.OnCreate();
Then the OnCreate function would know what properties are on the model:
public void OnCreate()
{
this.BirthdayMessage = "Happy Birthday";
etc...
}
I just see two issues here:
1 - In the controller I would need to test that the model implements IOnCreate--if it doesn't, I wouldn't try to call OnCreate().
2 - I need to be sure that adding a public function such as OnCreate() will not interfere with how EF6 generates database tables in a code-first project.
My question now is whether this approach be best... or whether there is any other idea to consider...
Since T is any type, compiler can't expect it having CurrentDate or SpecialProperty;
you could try solving the problem like that:
public interface IMyInterface {
DateTime CurrentDate {get; set}
String SpecialProperty {get; set}
}
public class MyClassA: IMyInterface {...}
public class MyClassB: IMyInterface {...}
public class MyClassC: IMyInterface {...}
...
private void OnCreate<T>(T value)
where T: IMyInterface // <- T should implement IMyInterface
{
value.CurrentDate = DateTime.Now;
value.SpecialProperty = "Hello";
}
By your example it seems unlikely the Generics are the the solution for you problem (your app), it would seems that a use of an abstract layer (Interface or Abstract Class) is more appropriate.
When using "bare bone" generics any Type can be passed to your method, now since any type in .Net is of type Object you can execute any object related functionality on those generics parameters. To extend this ability of the generics to implements the most basic type in the inheritance hierarchy we have Generics Constraints, those allow you to limit the range of types that can be passed as a generic argument. In your case you'd want to use Type Constraints, which limit the range of types to only those which implement the type specified.
For example, we have type A, and the A has types B and C as derived classes, we want method M to accept only type how implements A:
class Program
{
static void Main(string[] args)
{
M(new A()); // will work
M(new B()); // will work
M(new C()); // will work
M(new D()); // wont work
}
public static string M<T>(T arg)
where T : A
{
return arg.Data;
}
}
public class A { public string Data { get; set; } }
public class B : A { }
public class C : B { }
public class D { }
Edit
According to your last edit it would seems that you have two options to solve this problem.
Implementing an abstraction layer (an Interface): You may want to add an interface and implement it by your models.
public static void OnCreate(IBirthable arg)
{
arg.BirthDate = ...;
}
Interface:
public interface IBirthable
{
DateTime BirthDate { get; set; }
string BirthdayMessage { get; set; }
}
Models:
public class CustomerModel : IBirthable
{
public DateTime BirthDate { get; set; }
public string BirthdayMessage { get; set; }
}
public class AnotherModel : IBirthable
{
public DateTime BirthDate { get; set; }
public string BirthdayMessage { get; set; }
}
Using reflection: If you choose not to use an interface, perhaps is has no logical connection with your models you may want use reflection.
public static void OnCreate<T>(T arg)
{
var type = arg.GetType();
var birthDateProperty = type.GetProperty("BirthDate");
if (birthDateProperty == null)
throw new ArgumentException("Argument not is implementing the model");
birthDateProperty.SetValue(arg, DateTime.Now);
//And so on...
}
Models:
public class CustomerModel
{
public DateTime BirthDate { get; set; }
public string BirthdayMessage { get; set; }
}
public class AnotherModel
{
public DateTime BirthDate { get; set; }
public string BirthdayMessage { get; set; }
}
I'm trying to implement a Table, divided this up to 3 levels.
class Field ->
class Record (witch holds a collection of fields ) ->
class Table(witch holds a collection of Records)
now my question is not of the correct way to structure this implementation , although any pointers would be welcomed .
iv'e got a problem with implementing a generic field class
public class Field<T>
{
T value;
Type _type;
string _header;
}
i don't know what type T would be of so i need to define the class with ,
now the problem that i'm facing is that the collection of Field in the Record class would most likely hold different types of T and that kinda defeats the all purpose
public class Record
{
List<Field<object>> fields ;
}
so now i need to cast the T to object because T wont be of a specific type .
any idea's the work around this accept drooping the all generics idea and defining value as object , would be most appreciated.
plus any pointers about my implementation idea
my table consists of
class Table
{
KeyValuePair<string,Type>[] columns ;
KeyValuePair<string, Type> primary_key;
string entitie_name ;
List<Reocrd> records ;
}
// the Record class could be created only from a table template just like a datarow
public class Record
{
List<Field<object>> fields ;
string primary_key ;// the name of the field witch i use to extract a value
}
10x in advance.
A pattern you can commonly find in the .NET Framework is to define a non-generic base class or interface:
public abstract class Field
{
protected Field() { }
public abstract BoxedValue { get; set; }
public abstract Type ValueType { get; }
}
public class Field<T> : Field
{
private T value;
public Field(T value) { this.value = value; }
public T Value
{
get { return this.value; }
set { this.value = value;; }
}
public override object BoxedValue
{
get { return this.value; }
set { this.value = (T)value; }
}
public override Type ValueType
{
get { return typeof(T); }
}
}
The Record class exposes a collection of non-generic fields:
public class Record
{
public IEnumerable<Field> Fields { get { ... } }
}
If code needs to get the value of fields without boxing, it needs to cast the Field instance to the matching Field<T> first.
Example:
foreach (Field<int> field in record.Fields.OfType<Field<int>>())
{
int value = field.Value;
Console.WriteLine(value);
}
I tend to use interfaces here
IField ... make a generic class that uses this
Then inherit off this with a
IField interface
now you can have a List which would actually contain a list of IField
interface IField
{
object Data{get;set;}
}
interface IField<T> : IField
{
T TypedObject{get;set;}
}
Now you can have a List that has IField object added to it.
EDIT: I dont like to use base classes unless i really have to because that then removes the possibility of using inheritance later. Inheritance is a simple solution but comes with a whole host of caveats imo
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);
}
}