Class inheritance & constructors - c#

Hello to all the brilliant minds of StackOverflow!
I am getting familiar with c# class inheritance and multiple constructors but I can't seem to word a question that would allow me to Google it.
Here's what I have:
public class Order: OtherOrder
{
private OtherOrderManager _om;
public Order()
{
if (_om == null)
_om = new OtherOrderManager();
}
public Order(int orderID)
: base()
{
}
}
So obviously, now I can do something like:
Order order = new Order();
order.Member_From_OtherOrder_Class = "bleh";
But here's what I'm trying to implement in a constructor:
public class Order: OtherOrder
{
private OtherOrderManager _om;
public Order()
{
if (_om == null)
_om = new OtherOrderManager();
}
public Order(int orderID)
: base()
{
this = (Order)_om.GetOrder(orderID); //Returns an instance of OtherOrder
//Basically, I want to populate all the members of Order() interited
//from OtherOrder and fill them with data returned by this call.
}
}
Obviously, "this" is read only so that doesn't even compile. Is there any technical expression that would describe what I'm looking for ? Is it even possible ?
Thanks!
EDIT: I think I'll use reflection to loop through all members and get/set values this way.

Even though it's a bit vague about what you're trying to achieve, I'm guessing you might want to use something along the lines of using a factory possibly with copy-constructors. Essentially, the copy-constructors provide an easy means to populate data along the inheritance chain with your copies.
Consider the following base class:
public abstract class OrderBase
{
public int OrderID { get; private set; }
public string Name { get; protected set; }
public OrderBase()
{
}
public OrderBase(OrderBase copiedOrder)
{
this.OrderID = copiedOrder.OrderID;
this.Name = copiedOrder.Name;
}
}
(I left the parameterless constructor in there because I'm guessing it will be needed somewhere)
So an OrderBase can be instantiated by passing another OrderBase instance. Within that constructor, we know which properties to copy over and are compile-time checked.
Now a subclass might be:
public class CustomOrder : OrderBase
{
public Guid CustomID { get; private set; }
public CustomOrder()
{
}
public CustomOrder(CustomOrder copiedOrder)
: base(copiedOrder)
{
this.CustomID = copiedOrder.CustomID;
}
}
Here, the CustomOrder only copies its own property that is declared on it and passes the rest of the copying responsibility to the base class. Add one more class to the chain:
public class ValidatableCustomOrder : CustomOrder
{
public bool IsValid { get; private set; }
public ValidatableCustomOrder()
{
}
public ValidatableCustomOrder(ValidatableCustomOrder copiedOrder)
: base(copiedOrder)
{
this.IsValid = copiedOrder.IsValid;
}
}
And you can see how it can nicely manage each property set per subclass without any one class knowing much about the other. Your factory in turn might look something like:
public static class ValidatableCustomOrderLoader
{
public static ValidatableCustomOrder Get(int orderID)
{
ValidatableCustomOrder loadedOrder = LoadOrderFromSomewhere(orderID);
ValidatableCustomOrder copiedOrder = new ValidatableCustomOrder(loadedOrder);
return copiedOrder
}
private ValidatableCustomOrder LoadOrderFromSomewhere(int orderID)
{
//get your order somehow
}
}
So it (somehow) loads the data (perhaps from a database), copies it to a new instance which will chain through all the copy-constructors. Your calling code would look like:
int orderID = 10;
ValidatableCustomOrder order = ValidatableCustomOrderLoader.Get(orderID);
Anyhow, I can't say if this will specifically help you since your question/code seems a bit off-the-wall and vague, but hopefully it will help give you some ideas.

Two approaches come to mind: manually copy the properties:
public Order(int orderID)
: base()
{
var other = (Order)_om.GetOrder(orderID);
this.SomeProperty = other.SomeProperty; //repeat for each property/field that should be copied
}
Or use a static or factory method instead of constructors, e.g.:
public static Order GetOrder(int orderId)
{
return (Order)_om.GetOrder(orderID);
}

Try:
this._om = (Order)_om.GetOrder(orderID);
Hope that helps.

Related

Recursive constraints: What does DBase<T> : where T : DBase<T> mean?

I thought I understood generic constraints until I ran across this.
public class DBase<T> : DbContext, IDisposable where T : DBase<T>
How can T be DBase<T>?
And if it can, what does it mean?
This code compiles and runs fine. I'm not fixing a problem. I just don't understand it.
It is used here
public class ChildDb : DBase<ChildDb>
Which, again, doesn't compute for me. It passes itself as a type parameter?
How can T be DBase<T>?
There is no limitation that prevents a Generic Parameter from deriving from itself. While it's not directly understandable with the example you've given. What about a Vertex / Vertice?
Excerpt from Wikipedia:
In geometry, a vertex (plural: vertices or vertexes) is a point where two or more curves, lines, or edges meet. As a consequence of this definition, the point where two lines meet to form an angle and the corners of polygons and polyhedra are vertices.1
How does one describe a Vertex (a point)?
// very simplified example
public class Vertex
{
public int X { get; set; }
public int Y { get; set; }
}
Now how do we add a collection of relationed Verticies to this class but only allow things that derive from this class?
public class Vertex<TVertex> : Vertex
where TVertex : Vertex<TVertex>
{
public IEnumerable<TVertex> Vertices { get; set; }
}
It a generic version of say:
public Vertex2
{
public IENumerable<Vertex2> Vertices { get; set; }
}
However when I derive from Vertex2, my Vertices will always have to be IEnumerable<Vertex2>, and the correct way to allow Vertices to be a derived class is to use this type of self-reference generic.
I'm sorry Erik, I lost the point in the details. What have I gained by the recursion?
Using Vertex2, our derived types lose access to other derived properties:
public class MyVertex2: Vertex2
{
public int Id { get; set; }
}
so
var a = new MyVertex2 {Id = 1 };
var b = new MyVertex2 { Id = 2 };
a.Vertices = new List<Vertex2> { b };
b.Vertices = new List<Vertex2> { a };
// can't access Id because it's a Vertex2 not a MyVertex2
var bId = a.Vertices.First().Id;
Sure you could cast it, but then you're casting it everywhere (that's not DRY)... and what if it's not a MyVertex (MullReferencesException or InvalidCastException).
public class MyVertex: Vertex<MyVertex>
{
public int Id { get; set; }
}
var a = new MyVertex {Id = 1 };
var b = new MyVertex { Id = 2 };
a.Vertices = new List<MyVertex > { b };
b.Vertices = new List<MyVertex > { a };
var bId = a.Vertices.First().Id;
// or even
var aId = a.Vertices.First().Vertices.First();
each time we navigate to a vertices we get the correct derived type, not the base class.
John Wu posted a great blog in the comments, the TLDR of which is:
This code pattern allows you to declare a superclass that must be extended (possibly not by you, if you're writing a library that other people will use) in order to be used, but can have a bunch of methods/signatures (written by you) that return T when you write them but in practice will return objects of the child type (not written by you/you cannot know) so they can be used in a chained fashion (like the way most StringBuilder methods return the StringBuilder itself so the user can call .Append().AppendLine() ) without needing to be cast (in the code not written by you) from the parent type (written by you) to the child type (not written by you)
There's a caveat: it's not particularly useful because only the deepest child in an inheritance tree can be instantiated. Avoid using it
As a useful example, it allows you to have some methods or properties in the base class which return derived type.
For example, in the fluent builders which have chainable methods, let's say we have a base builder which set some common properties. What should be the output type of these methods?
See the following example:
public abstract class Control
{
public string Id { get; set; }
}
public abstract class ControlBuilder<TBuilder, TControl>
where TBuilder : ControlBuilder<TBuilder, TControl>, new()
where TControl : Control, new()
{
protected TControl control;
protected ControlBuilder()
{
control = new TControl();
}
public static TBuilder With()
{
return new TBuilder();
}
public TControl Build()
{
control;
}
public TBuilder Id(string id)
{
control.Id = id;
return (TBuilder)this;
}
}
Without having ControlBuilder<TBuilder, TControl> as a constraint for TBuilder, how you can return a TBuilder from Id method?
If you say ask why not return ControlBuilder<TBuilder, TControl>, because if you return it, after calling .Id("something") in method chains, it will not show derived class methods and it just will show methods of ControlBuilder<TBuilder, TControl>.
Let's say we create a TextBoxBuilder for building a TextBox:
public class TextBox : Control
{
public string Text { get; set; }
}
public class TextBoxBuilder : ControlBuilder<TextBoxBuilder, TextBox>
{
public TextBoxBuilder Text(string text)
{
control.Text = text;
return this;
}
}
Now we can use it as expected:
var txt = TextBoxBuilder.With().Id("textBox1").Text("Hello!").Build();

Handling the interacton of intances of classes belong to two parallel inhertiance groups

I have two groups of classes in my code and one group has logic and other group has data and inheritance is also being used in each group. I tried to mimic the situation which I am dealing with in below code snippet. The problem I have is how to handle the objects of derived data classes efficiently in related instances of logic classes. Right now I am trying to cast the instance of derived data class in a method of derived logic class which I do not think is logical. I need some guidance to address this issue.
void Main()
{
var item1 = new D1();
var holder1 = new DataHolder1() { localProp1 = "test" };
var holderout = item1.Method1(holder1);
holderout.Dump();
}
public class BaseDataHolder
{
public string prop { get; set; }
}
public class DataHolder1 : BaseDataHolder
{
public string localProp1 { get; set; }
}
public class DataHolder2 : BaseDataHolder
{
public string localProp2 { get; set; }
}
public class BaseClass
{
public virtual BaseDataHolder Method1(BaseDataHolder holder)
{
return null;
}
}
public class D1 : BaseClass
{
public override BaseDataHolder Method1(BaseDataHolder holder)
{
(holder as DataHolder1).localProp1.Dump();
(holder as DataHolder1).localProp1 = "change1";
return holder;
}
}
public class D2 : BaseClass
{
public override BaseDataHolder Method1(BaseDataHolder holder)
{
(holder as DataHolder2).localProp2.Dump();
(holder as DataHolder2).localProp2 = "change2";
return holder;
}
}
I don't see why it would be illogical since looks like you are trying to get DataHolder1 always in class D1. Rather, why can't your class compose with Data class instance and use that in method like
public class D1 : BaseClass
{
private readonly DataHolder1 holder;
public D1(DataHolder1 holder) { this.holder = holder; }
public override BaseDataHolder Method1()
{
holder.localProp1.Dump();
holder.localProp1 = "change1";
return holder;
}
}
Then you can just say
var item1 = new D1(new DataHolder1());
BaseDataHolder data = item1.Method1();
This violates the Liskov substitution principle. In summary, it's bad, because your signature promises to work well with any BaseDataHolder but in reality it will just crash if the wrong BaseDataHolder is passed in.
I cannot really give a solution because we don't know your requirements. From what you have posted, your three logic classes should drop the inheritance and just have three different method signatures, each telling what it needs instead of all of them lying about what they need and then crashing randomly.

inheritance, or should i use composition?

Lets say i have a class
public class Transfer
{
prop1
prop2
....
public List<SubTransfer> SubTransfers { get; set; }
}
Which i get from a function that connects to a database
Now i want to have a class that adds a status, both to the Transfer and to each one of the SubTransfer.
One question is if i should use inheritance here? or composition?
I think inheritance, so im trying to do something like this:
public ExtendedSubTransfer : SubTransfer
{
public StatusEnum Status { get; set; }
}
public ExtendedTransfer : Transfer
{
public StatusEnum Status { get; set;}
}
My problem is i dont know how to do that ill get a list of ExtendedSubTransfer when using ExtendedTransfer.
I know i can override SubTransfers using the keyword new like this:
public new List<ExtendedSubTransfers> SubTransfers {get; set;}
Is it "legit"? Or do you have other suggestions?
Thanks for the help!
It will compile but it probably isn't going to do what you want. Keep in mind that List<ExtendedSubTransfer> does not extend List<SubTransfer>. For example, if you have any operation that uses the base class you will not get what you want. To demonstrate, let us pretend the base class has an ID and you want to print the IDs.
public void PrintIds()
{
ExtendedTransfer extendedTransfer = _database.GetExtendedTransfer(...);
PrintSubTransferIds(extendedTransfer);
}
private PrintSubTransferIds(Transfer transfer)
{
foreach(var subTransfer in transfer.SubTransfers)
{
Console.WriteLine(subTransfer.Id);
}
}
The above method will not work unless you do something very strange when loading the items from the database. For example, if your loading code looks like...
public GetExtendedTransfer(...)
{
ExtendedTransfer result = new ExtendedTransfer();
List<ExtendedSubTransfer> subTransfers = _connection.QueryForSubTransfers(...);
result.SubTransfers = subTransfers;
return result;
}
Then it will not work. It will not print any subtransfer ids because transfer.SubTransfers will be an empty list. Instead you'd have to do something weird when loading from the database like...
public GetExtendedTransfer(...)
{
ExtendedTransfer result = new ExtendedTransfer();
List<ExtendedSubTransfer> subTransfers = _connection.QueryForSubTransfers(...);
result.SubTransfers = subTransfers;
Transfer subtypedResult = result;
subtypedResult.SubTransfers = subTransfers.Cast<SubTransfer>();
return result;
}
Also, the following case would be a compile time error:
public void PrintIds()
{
ExtendedTransfer extendedTransfer = _database.GetExtendedTransfer(...);
PrintSubTransferIds(extendedTransfer.SubTransfers);
}
private PrintSubTransferIds(List<SubTransfer> subTransfers)
{
foreach(var subTransfer in subTransfers)
{
Console.WriteLine(subTransfer.Id);
}
}
This would fail to compile because extendedTransfer.SubTransfers is of type List<ExtendedSubTransfer> which cannot be assigned to List<SubTransfer>.
Update: So what should you do?
C# (4.X and above) allows covariance on certain interfaces such as IReadOnlyList (C# 4.5 and above). Thus you can do...
public class Transfer
{
public virtual IReadOnlyList<SubTransfer> SubTransfers { get; private set; }
public void SetSubTransfers(List<SubTransfer> subTransfers)
{
SubTransfers = subTransfers;
}
}
public class ExtendedTransfer
{
private List<ExtendedSubTransfer> _subTransfers;
public override IReadOnlyList<SubTransfer> SubTransfers
{
get { return _subTransfers; }
}
public void SetSubTransfers(List<ExtendedSubTransfer> subTransfers)
{
_subTransfers = subTransfers;
}
}
This would be my best attempt at solving your problem. However, you didn't mention how you are getting your entities from the database. I don't think EntityFramework would be very happy with this field arrangement by default.

How to inherit a static property with a unique value for each subclass?

I have a series of objects, lets call them buildings, that each share certain properties that are static for that building, but different for each building, such as price. I assumed that the best way to implement this was to create an abstract superclass with the shared price attribute and set the values in each subclass, but I cannot figure out how to get this to work. Here is an example of something I have tried:
using System;
public abstract class Buildings
{
internal static int price;
internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
public Walls()
{
price = 200;
turnsToMake = 5;
}
}
This works fine for construction, but if I want to check the price before creating it (to check if the player has enough money) then it just returns a null value. I'm sure that it is is a super simple fix, but I can't figure it out. Any help?
There is a "patchy" yet simple solution that's worth to consider. If you define your base class as a Generic class, and in deriving classes set T as the class itself, It will work.
This happens because .NET statically defines a new type for each new definition.
For example:
class Base<T>
{
public static int Counter { get; set; }
public Base()
{
}
}
class DerivedA : Base<DerivedA>
{
public DerivedA()
{
}
}
class DerivedB : Base<DerivedB>
{
public DerivedB()
{
}
}
class Program
{
static void Main(string[] args)
{
DerivedA.Counter = 4;
DerivedB.Counter = 7;
Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
Console.ReadLine();
}
}
Don't use static. Static says that all instances of Building have the same value. A derived class will not inherit its own copy of the statics; but would always modify the base class statics. In your design there would only be one value for price and turnsToMake.
This should work for you:
public abstract class Buildings
{
internal int price;
internal int turnsToMake;
}
However, most people don't like using fields these days and prefer properties.
public abstract class Buildings
{
internal int Price { get; set; }
internal int TurnsToMake { get; set; }
}
I want to check the price before creating it […]
I suppose that's how you got to static fields; however, static and virtual behaviour cannot be combined. That is, you would have to re-declare your static fields for each subclass. Otherwise, all your subclasses share the exact same fields and overwrite each others' values.
Another solution would be to use the Lazy<T, TMetadata> type from the .NET (4 or higher) framework class library:
public class Cost
{
public int Price { get; set; }
public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
valueFactory: () => new Walls(),
metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
var buildings = lazyBuildings.Value;
}
That is, the metadata (.Metadata) now resides outside of the actual types (Buildings, Walls) and can be used to decide whether you actually want to build an instance ( .Value) of it.
(Thanks to polymorphism, you can have a whole collection of such "lazy factories" and find a building type to instantiate based on the metadata of each factory.)
Building on Uri Abramson's answer above:
If you need to access the static property from within the Base class, use reflection to get the value from T. Also, you can enforce that Base must be inherited using T of the derived type.
e.g.
class Base<T> where T : Base <T> {
static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
{
return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
}
static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}
If you have a better way to do this, please post.
Not as easy for the inheritor, but workable...
public abstract class BaseType
{
public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
protected static contentType _inheritedTypeContent;
public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}

No base class problem, How to use Castle.DynamicProxy Mixin in this particular case?

I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:
public interface ISomeType<V>
{
V Value {get; set;}
}
public interface ISomeTypeWrapper
{
object Value { get; set; }
}
public class SomeTypeWrapper<T> : ISomeTypeWrapper
where T : ISomeType<???>
{
T someType;
public SomeTypeWrapper(T wrappedSomeType)
{
someType = wrappedSomeType
}
public object Value
{
get { return someType.Value; }
set { someType.Value = value != null ? value : default(T); }
}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.
I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.
How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)
How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?
You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.
container
.Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
.Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());
You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.
Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:
public class SomeTypeWrapperFactory
{
public ISomeType<int> CreateWrapper(SomeType1 someType1)
{
return new SomeType1Wrapper(someType1);
}
public ISomeType<string> CreateWrapper(SomeType2 someType2)
{
return new SomeType2Wrapper(someType2);
}
}
public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }
Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.
Why SomeTypeWrapper but not SomeObjectWrapper?
public class SomeObjectWrapper : ISomeType
{
Object _someObject;
PropertyInfo _valuePropertyInfo;
public SomeObjectWrapper(Object wrappedSomeObject)
{
_someObject = wrappedSomeObject;
_valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
}
public object Value
{
get { return _valuePropertyInfo.GetValue(_someObject, null); }
set { _valuePropertyInfo.SetValue(_someObject, value, null); }
}
}
Edited With .NET 3.5 using LinFu
You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution.
In that case I would personally choose Orsol's solution.
However: here's an example with LinFu's ducktyping.
public interface ISomeType {
object Value{get; set;}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeWrapperFactory
{
public static ISomeType CreateSomeTypeWrapper(object aSomeType)
{
return aSomeType.CreateDuck<ISomeType>();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
foreach(var o in someTypes)
{
Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
}
Console.ReadLine();
}
}
Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).
With .NET 4 using dynamic
See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern.
In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeVisitor
{
public void VisitAll(object[] someTypes)
{
foreach(var o in someTypes) {
// this should be in a try-catch block
Console.WriteLine(((dynamic) o).Value);
}
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
var vis = new SomeTypeVisitor();
vis.VisitAll(someTypes);
}
}

Categories

Resources