I have two similar classes A and B, which contain the following code:
//A or B depending on class
public class LogicA
{
public List<Members> MembersA { get; set; } = new List<Member>();
public void AddMember(Member member)
{
MembersA.Add(member);
}
public List<Member> GetResultA()
{
return MembersA;
}
}
I want to use the MembersA and MembersB lists in another class (say logicC).
I have seen similar questions and they mostly involve single inheritance. The process I thought to use was to create instance of lists from two different classes in the third class through multiple inheritance but in C#, only interface support multiple inheritance and I am using classes, hence my issue.
Is there any reason that you need to use inheritance only?
Generally, the way of using a member of Class is follow
class logicC
{
static void Main(string[] args)
{
LogicA logicA = new LogicA();
LogicB logicB = new LogicB();
List<Member> memberA = logicA.memberA;
List<Member> memberB = logicB.memberB;
}
}
Both Logica.GetResultA and presumably LogicB.GetResultB return List<Member>. So there is no problem
LogicC can be
class LogicC{
void NoodleOnList(List<Member> input){
....
}
}
then
LogicC lc;
lc.NoodelOnList(la.GetMembersA());
lc.NoodelOnList(lb.GetMembersb());
Well, you should re-consider your design choices and think about how to make your code less prone to change.
You can create a new class to aggregate Lists from A, B. And via Composition this new class might access Lists from other inner objects.
public class logicC {
public LogicA logicA;
public LogicB logicB;
public List<Member> GetResultC() => logicA.GetResultA().Concat(logicB.GetResultB());
}
you can use static modifier for your methods for example:
public static class LogicA
{
public static List<Members> MembersA { get; set; } = new List<Member>();
public static void AddMember(Member member)
{
MembersA.Add(member);
}
public static List<Member> GetResultA()
{
return MembersA;
}
}
and use this like that:
using YourProject;
public class LogicC
{
Members members = new();
List<Members> membersList = new();
LogicA.AddMember(member);
membersList = LogicA.GetResult();
}
I have a third party DLL that returns objects like Customers, Orders, etc. I'll call them Your Entities. They do have a common IYourEntity interface so I can use that as a source constraint.
I want to create a generic conversion extension method to convert all these different third party entities to My Entities with some streamlined and more maintainable code.
....but I can't figure out how to make a generic extension method that will call the concrete extension method for the specific conversion of each class.
Putting some of the main aspects of my code below, but you can get a full fiddle to play with here.
Yes, I'm probably showing I'm a bit clueless on how to do this and maybe trying to combine different concepts. Any pointers much appreciated as I've been beating my head for a couple of days now and need a life line :)
public interface IYourEntity
{
int Id
{
get;
set;
}
}
public interface IConvertToMyEntity<TYourEntity, TMyEntity>
where TYourEntity : class, IYourEntity, new()
where TMyEntity : class, IMyEntity, new()
{
TMyEntity ToMyEntity(TYourEntity yourEntity);
}
public static class ExtensionMethods
{
private static IMyEntity ToMyEntity(this IYourEntity yourEntity)
{
return new MyEntity1();
}
public static List<IMyEntity> ToMyEntityList(this List<IYourEntity> lstYourEntities)
{
return lstYourEntities.ConvertAll(q => q.ToMyEntity());
}
}
public class YourEntity1 : IYourEntity, IConvertToMyEntity<YourEntity1, MyEntity1>
{
public int Id
{
get;
set;
}
public string YourEntityName
{
get;
set;
}
public MyEntity1 ToMyEntity(YourEntity1 yourEntity)
{
return new MyEntity1()
{Id = yourEntity.Id, MyEntityName = yourEntity.YourEntityName, CreatedOn = DateTime.UtcNow};
}
public List<MyEntity1> ToMyEntityList(List<YourEntity1> lstYourEntities)
{
return lstYourEntities.ConvertAll(q => ToMyEntity(q));
}
}
Since the classes implementing IYourEntity are from a third party and not under your control, you can't implement an own IConvertToMyEntity<T1, T2> interface upon these.
One way you can handle it is by overloads of such conversion (extension) methods.
There's no need for any generic T type arguments; the common IYourEntity interface suffices.
Suppose you have 3 classes implementing the IYourEntity interface;
e.g. YourCustomer, YourOrder and YourProduct.
These need to be converted to IMyEntity instances, of which you might have different concrete implementations;
e.g. a general MyEntity and a specific MyProduct.
For the conversion you set up an extension method targeting IYourEntity.
This extension method will be called to convert an IYourEntity to an IMyEntity in case a more specific overload of this extension method does not exist.
public static IMyEntity ToMyEntity(this IYourEntity target)
{
return new MyEntity { Id = target.Id, EntityName = "Fallback name" };
}
For the entities that require a custom conversion, you set up overloads of this extension method targeting those specific source class types.
Below are such ones for YourOrder and YourProduct (but not for YourCustomer).
public static IMyEntity ToMyEntity(this YourOrder target)
{
return new MyEntity { Id = target.Id, EntityName = target.OrderName.ToUpper() };
}
public static IMyEntity ToMyEntity(this YourProduct target)
{
return new MyProduct { Id = target.Id * 100, EntityName = target.ProductName };
}
Next, define the extension method to convert the list of IYourEntity instances to a list of IMyEntity instances. In the code below, the inbetween cast to dynamic enables that the appropriate ToMyEntity overload will be called.
Note that the ToMyEntity methods don't have to be extension methods, but it might be convenient to have these in place in case you need to convert a single instance instead of a list.
public static List<IMyEntity> ToMyEntities(this List<IYourEntity> target)
{
var myEntities = new List<IMyEntity>();
foreach (var yourEntity in target)
{
var myEntity = Extensions.ToMyEntity((dynamic)yourEntity);
myEntities.Add(myEntity);
}
return myEntities;
}
An example - .net fiddle
var yourEntities = new List<IYourEntity>()
{
new YourCustomer() { Id = 1 },
new YourOrder() { Id = 2, OrderName = "Order-2"},
new YourProduct() { Id = 3, ProductName = "Product-3"}
};
var myEnties = yourEntities.ToMyEntities();
myEnties.ForEach(o => Console.WriteLine("{0} - {1} ({2})",
o.Id, o.EntityName, o.GetType().Name
));
The output of the example above looks like below.
Notice how the YourCustomer instance was handled by the general IYourEntity conversion, whereas the YourOrder and YourProduct instances got a specific treatment.
1 - Fallback name (MyEntity)
2 - ORDER-2 (MyEntity)
300 - Product-3 (MyProduct)
You can change your extension method to this:
private static IMyEntity ToMyEntity(this IYourEntity yourEntity)
{
if (yourEntity is IConvertToMyEntity<IYourEntity, IMyEntity> convertible)
return convertible.ToMyEntity;
return new MyEntity1();
}
This will not work in most cases unless you also make your interface co- and contra-variant:
public interface IConvertToMyEntity<in TYourEntity, out TMyEntity>
where TYourEntity : class, IYourEntity, new()
where TMyEntity : class, IMyEntity, new()
{
TMyEntity ToMyEntity(TYourEntity yourEntity);
}
It is still not completely clear to me how you can make a third party class implements IConvertToMyEntity that easily. Assuming you did this only to show us your actual goal, you should be very careful with what you are trying to accomplish in the Main.
If you use a List<IYourEntity>, you can only use methods and properties defined in the interface, unless you know what you are doing with specific cast. The need for List<IYourEntity> or List<IMyEntity> limits a lot the implementation of a custom mapper between My classes and Your classes. Here a possible solution:
As I said, I did not change Your classes:
public interface IYourEntity
{
int Id
{
get;
set;
}
}
public class YourEntity1 : IYourEntity
{
public int Id
{
get;
set;
}
public string YourEntityName
{
get;
set;
}
}
Also My classes are very simple and do not contain any logic for the mapping. This is a debatable choice, but I generally prefer to keep conversion logic separated from the classes involved. This helps to maintain clean your code in case you have several conversion functions for the same pair of classes. By the way, here they are:
public interface IMyEntity
{
int Id
{
get;
set;
}
DateTime CreatedOn
{
get;
set;
}
}
public class MyEntity1 : IMyEntity
{
public int Id
{
get;
set;
}
public string MyEntityName
{
get;
set;
}
public DateTime CreatedOn
{
get;
set;
}
}
And this is how I designed the custom converter
public interface IMyEntityConverter
{
IMyEntity Convert(IYourEntity yourEntity);
}
public class MyEntity1Converter : IMyEntityConverter
{
public IMyEntity Convert(IYourEntity yourEntity)
{
var castedYourEntity = yourEntity as YourEntity1;
return new MyEntity1()
{
Id = castedYourEntity.Id,
MyEntityName = castedYourEntity.YourEntityName,
CreatedOn = DateTime.UtcNow
};
}
}
It is clear the lack of genericity, but you cannot do otherwise if you need an extension method on a List of generic My and Your classes. Also tried with covariant and contravariant interfaces but C# does not let you use them with this implementation.
Now the core of the solution: you need something that binds Your class to the My class with a custom converter, and all of this should be as more transparent as possible.
public class EntityAdapter<YourType, MyType>
where YourType : IYourEntity
where MyType : IMyEntity
{
protected YourType wrappedEntity;
protected IMyEntityConverter converter;
public EntityAdapter(YourType wrappedEntity, IMyEntityConverter converter)
{
this.wrappedEntity = wrappedEntity;
this.converter = converter;
}
public static implicit operator YourType(EntityAdapter<YourType, MyType> entityAdapter) => entityAdapter.wrappedEntity;
public static explicit operator MyType(EntityAdapter<YourType, MyType> entityAdapter) =>
(MyType) entityAdapter.converter.Convert(entityAdapter.wrappedEntity);
public MyType CastToMyEntityType()
{
return (MyType) this;
}
}
The pseudo-transparency here is given by the implicit cast to Your class. The advantage is that you can cast this EntityAdapter to an instance of a My class by calling CastToMyEntityType or the explicit operator overload.
The painful part is with the extension methods:
public static class EntityAdapterExtensions
{
public static List<IMyEntity> ToIMyEntityList(this List<EntityAdapter<IYourEntity, IMyEntity>> lstEntityAdapters)
{
return lstEntityAdapters.ConvertAll(e => e.CastToMyEntityType());
}
public static List<EntityAdapter<IYourEntity, IMyEntity>> ToEntityAdapterList(this List<IYourEntity> lstYourEntities)
{
return lstYourEntities.Select(e =>
{
switch (e)
{
case YourEntity1 yourEntity1:
return new EntityAdapter<IYourEntity, IMyEntity>(yourEntity1, new MyEntity1Converter());
default:
throw new NotSupportedException("You forgot to map " + e.GetType());
}
}).ToList();
}
}
The first one is pretty straightforward to understand, but the second one is definitely something that require maintenance. I gave up on generics for the reasons already explained, so the only thing left to do is to create the EntityAdapters starting from the actual entity types.
Here is the fiddle
This may be a little controversial but maybe a different way is better?
Firstly, and this is more for my sake, I would suggest more easily understandable terminology so instead of 'your' and 'my' I would use 'source' and 'dest'.
Secondly I wonder if the generics route is necessary? I'm assuming (and I may be wrong) that for each of the classes you have coming from your third-party assembly, you have a specific class for it to be converted to. So maybe this could be achieved much more easily with a constructor override in your destination class.
// third party class example
public class SourceClass
{
public int Id { get; set; }
public string Name { get; set; }
}
// the destination class in your project
public class DestClass
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
// default constructor
public DestClass()
{
}
// conversion constructor
public DestClass(SourceClass source)
{
Id = source.Id;
Name = source.Name;
CreatedOn = DateTime.UtcNow;
}
}
This way you convert a single instance using:
// source being an instance of the third-party class
DestClass myInstance = new DestClass(source);
And you can convert a list with LINQ:
// source list is IList<SourceClass>
IList<DestClass> myList = sourceList.Select(s => new DestClass(s)).ToList();
If you wanted to you could implement extensions for your conversions. This again would not be generic as you'll need one for each class pairing but as it's an alternative to writing a converter class for each, it will be overall less code.
public static class SourceClassExtensions
{
public static DestClass ToDest(this SourceClass source)
=> new DestClass(source);
public static IList<DestClass> ToDest(this IList<SourceClass> source)
=> source.Select(s => new DestClass(s)).ToList();
}
If you still want something generic then you'll want a converter for each class pair, implementing a suitable interface. Then I'd recommend a converter factory class where you'll need to register the specific converters either into a dictionary in the class or via dependency injection. I can go into this further if you'd prefer but I think it would be more complicated.
sorry for writing here its not an actual answer,
there is no option for generically to do this
you have to write for every entity
public interface IConvertToMyEntity<TYourEntity, TMyEntity>
where TYourEntity : class, IYourEntity, new()
where TMyEntity : class, IMyEntity, new()
{
TMyEntity ToMyEntity(TYourEntity yourEntity);
}
I saw this code from your question.
It depends on what you want to do after transformation
you should use data mapper
public class MapProfile : Profile
{
public MapProfile()
{
CreateMap<TYourEntity , TMyEntity >();
CreateMap<TMyEntity , TYourEntity >();
}
}
Let's say I have an interface called ITranslation and two classes which implement it called NameTranslation and DescriptionTranslation:
interface ITranslation {
string text { get; set; }
}
class NameTranslation: ITranslation {
public string text { get; set; }
}
class DescriptionTranslation: ITranslation {
public string text { get; set; }
}
I then want to be able to call a method with both of them.
public void DoStuff(ITranslation) { ... };
And the above works fine!
Say I re-implement my DoStuff method to take in a generic collection of my interfaces:
public void TryIt()
{
ICollection<ITranslation> myList = new List<ITranslation>();
DoStuff(myList);
}
public void DoStuff(ICollection<ITranslation> Param) { }
Works fine too!
But the moment I switch it to
ICollection<NameTranslation> myList = new List<NameTranslation>();
C# says that it is unable to cast it.
Why is this? How can I achieve it?
I want to go from ICollection<NameTranslation> to ICollection<ITranslation>
I believe if you change your DoStuff method to:
public void DoStuff<T>(ICollection<T> Param) where T : ITranslation { }
will fix your issue
You should be operating on the ITranslation like so:
ICollection<ITranslation> myList = new List<NameTranslation>();
If for some reason you need the Concrete Name Translation, and cannot have an ITranslation use the cast method
myList.Cast<ITranslation>.ToList()
Or just Operate using Generics
public void DoStuff<T>(ICollection<T> Param)
where T : ITranslation
I currently have a class which encapsulates a list of typed objects and implements some interfaces like IEnumerable. I need a second class with additional, slightly different properties. So I will be creating a base class A and derive new class B and new class C from A.
However I have code (e.g like code for .Find using Delegates) which is almost the same in B and C. The only difference is that the code in B searches the private list of typed objects (let's say Person) and the code in C searches a private list of different objects (let's say Animal):
private static bool Find(Person xx)
{
if (xx.Id == someID)
{
return true;
}
else
{
return false;
}
}
As I want to avoid copying/pasting, my question is: What is a good strategy to avoid something like that?
The only way I imagined was to declare a list of generic objects in A and point the methods in A to that. In B and C I would then not have any code, however I lose all benefits of a typed list.
1) I would see if I could use generics when coding class A
public class cA<T>
{
private IEnumerable<T> _myPrivateData
public bool Find(args)
{
// Do stuff with _myPrivateData
}
}
public class cB : cA<TheTypeIWant>
{
// more stuff here if needed
}
2) You can use the property override feature + the use of the protected access modifier to do the following:
public class cA
{
protected IEnumerable<Object> MyData { get; set; }
public bool Find(args)
{
// Do stuff with MyData
}
}
public class cB : cA
{
protected new IEnumerable<MyOtherDataType> MyData { get; set; }
}
Of course MyOtherDataType has to inherit from the base type used for this approach to be possible. I would really not recommend this approach though. Option 1 is much better and cleaner.
Here's a few references that may prove to be useful:
http://peisker.net/dotnet/covariance.htm
C#: Overriding return types
I'd be tempted to have an interface like ICanBeFoundById
public interface ICanBeFoundById
{
int Id {get;}
}
then Person and Animal can both inherit from that and you can do something like
public static class FindExtensions
{
public static bool Find(this IEnumerable<ICanBeFoundById> xs, int someID)
{
return xs.Any(x=>x.Id == someID)
}
}
Warning: I haven't even checked if this compiles :)
Of course you could have some
public abstract class BaseRepository<ICanBeFoundById>
{
private IEnumerable<ICanBeFoundById> _xs;
public static bool Find(int someID)
{
return xs.Any(x=>x.Id == someID)
}
}
if you don't want to have a static extension.
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.