inheritance, or should i use composition? - c#

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.

Related

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.

Dealing with badly designed models from third party API

In company I work for I am forced to use badly designed models from the third party API I have no access to like:
class Player
{
object Id;
object Name;
}
Each time I use these properties I have to cast them to specific type.
var name = player.Name.ToString();
var id = (int)player.Id;
And I have to lookup the database what the type is.
I was thinking to create exactly the same classes and using something like AutoMapper to map it to my own type each time and create some proxies/wrapper classes over the original ones.
Any solution?
There are two ways I would do this. Either using an extension method or by simply creating your new class with a static Convert method that take the badly designed class as a parameter.
Example 1:
namespace ExcellentDesignedClasses
{
public class NewPlayerClass
{
public NewPlayerClass(int id, string name)
{
Id = id;
Name = name;
}
public static NewPlayerClass Convert(Player player)
{
return new NewPlayerClass((int)player.Id, (string)player.Name);
}
public int Id { get; set; }
public string Name { get; set; }
}
}
Example 2: using Extension Methods
namespace ExcellentDesignedClasses
{
public class NewPlayerClass
{
public NewPlayerClass(int id, string name)
{
Id = id;
Name = name;
}
public int Id { get; set; }
public string Name { get; set; }
}
}
namespace ExcellentDesignedClasses.Extensions
{
public static class Extensions
{
public static NewPlayerClass ConvertToNew(this Player player)
{
return new NewPlayerClass((int)player.Id, (string)player.Name);
}
}
}
namespace MyProgram
{
using ExcellentDesignedClasses.Extensions;
public class Main
{
public void DoSomething()
{
var oldClassStructure = new Player();
var newClassStructure = oldClassStructure.ConvertToNew();
}
}
}
One thing you could do is create an extension method for the properties you care about. The nice thing is it's less work up front: just create an extension method when you find yourself needing to do a cast. You don't have to write any full classes or mapping code. The downside is you have to call a method every time you need a strongly typed property.
For example:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static string GetName(this Player p)
{
return p.Name?.ToString();
}
public static int GetId(this Player p)
{
return Convert.ToInt32(p.Id);
}
}
}
Then your code would look like:
string name = player.GetName();
int id = player.GetId();
I've worked for companies like this. They're the kind that still ask you in the interview if you know .Net, and you find out they mean version 1.1 on an old instance of Server 2003 they need maintained. They're the burnt raisins in the Raisin Bran.
Use inheritance to redefine the craptastic models. That's how I usually fix it. Then, I return what I want from my objects and stop using the classes I based them on.
ex:
class Player
{
public object Id;
public object Name;
}
class UserPlayer : Player
{
public new int Id
{
get
{
return Convert.ToInt32(base.Id);
}
set
{
base.Id = value;
}
}
public new string Name
{
get
{
return base.Name.ToString();
}
set
{
base.Name = value;
}
}
}
A runner up idea for when doing the above will get you in trouble because the person who wrote the code still works for the company and has friends or is, worse, your boss: use a static class to process what you want.
public static class ProcessPlayers
{
public static int ID(Player p)
{
return Convert.ToInt32(p.Id);
}
public static string Name(Player p)
{
return p.Name.ToString();
}
}
You can also just make new objects that each wrap around Player by having a Player as a property, but inheriting the object and overriding its properties is likely the better choice.

Generic Interface type conversion issues

I have been battling with this bit of code for a while now and I am trying to get a solution as it is literally the last part before it goes to testing.
I have the following interfaces and classes (simplified to the relevant parts):
public interface ITagParent<T> where T : ITag
{
List<TagAddOn<T>> TagCollection { get; set; }
}
public interface ITag
{
int Id { get; set; }
string Description { get; set; }
TagGroup TagGroup { get; set; }
}
public class TagAddOn<T> : ViewModelBase where T : ITag
{
private T _currentTag;
public T CurrentTag
{
get { return _currentTag; }
set { _currentTag = value; }
}
}
public partial class Customer : ITagParent<CustomerTag>
{
List<TagAddOn<CustomerTag>> _tagCollection;
public List<TagAddOn<CustomerTag>> TagCollection
{
get { return _tagCollection; }
set { _tagCollection = value; }
}
}
public partial class CustomerTag : ITag
{
public int Id { get; set; }
}
public class TagAddOnManager
{
public static string GetTagCurrentValue(List<TagAddOn<ITag>> dataObjectAddOns)
{
// LOTS OF SNIPPING!
return string.Empty;
}
}
I am trying to use the GetTagCurrentValue method in the TagAddOnManager class like this:
string value = TagAddOnManager.GetTagCurrentValue(
((ITagParent<ITag>)gridCell.Row.Data).TagCollection));
Everything compiles fine, but errors when trying to cast gridCell.Row.Data to ITagParent<ITag>. I understand this is due to covarience and a workaround (if not a terribly safe one) is to mark T in the ITagParent interface with the out keyword, but that won't work as you can see it is used in the TagCollection property, which can't be read only.
I tried casting the above to ITagParent<CustomerTag>, but this fails at compile time with a 'cannot convert' error when trying to feed it into my GetTagCurrentValue method.
Another option I considered is using some base classes instead of the ITagParent interface, but that won't work as the Customer object already inherits from another base class, which can't be modified for this implementation.
I know I could just overload the GetTagCurrentValue method with List<TagAddOn<CustomerTag>> as the parameter type and all other variations, but that really seems like a 'I give up' solution. I could probably use reflection to get the desired results, but that would be unwieldy and not very efficient, especially considering this method could be called a lot in a particular process.
So does anyone have any suggestions?
Could you use something like that
public class TagAddOnManager
{
public static string GetTagCurrentValue<TTag>(ITagParent<TTag> tagParent)
where TTag : ITag
{
// Just an example.
return tagParent.TagCollection.First().CurrentTag.Description;
}
}
and use it like that?`
var value = TagAddOnManager.GetTagCurrentValue((Customer)CustomergridCell.Row.Data);

Class inheritance & constructors

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.

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