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
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 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.
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(); }
}
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.
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);
}
}