implementing abstract class using derived types - c#

this may be somewhere else under generic types but I cant seem to follow a lot of the answers. Apologies if this is a repeat of another question.
the following code is for a three layer app with Data, Logic and Presentation Layers
in my data layer I have a Collection of entitys and a base entity
public abstract class BaseEntity
{
int LastModifiedBy { get; set; }
DateTime LastModifiedDate{get;set;}
}
public partial class DocNum: BaseEntity
{
}
public partial class DataList: BaseEntity
{
}
in my logic layer I have a BaseDTO class for transferring data. here is the code for it
public abstract class BaseDTO
{
protected abstract void ConvertFromEntity(BaseEntity entity);
public abstract void ConvertToEntity();
}
I then go and create the implementation class DocNum based on it as follows
public class DTODocNum : BaseDTO
{
//properties here
public DTODocNum()
{
}
public DTODocNum(DocNum entity)
{
ConvertFromEntity(entity)
}
protected override void ConvertFromEntity(DocNum entity)
{
throw new NotImplementedException();
}
public override void ConvertToEntity()
{
throw new NotImplementedException();
}
}
however this will not compile telling me that no suitable method to override was found.
I know I can do the following but I want thhis method to only accept a DocNum entity from the Data Layer:
protected override void ConvertFromEntity(BaseEntity entity)
{
throw new NotImplementedException();
}
I have also tried generic types with the following
public abstract class BaseDTO
{
protected abstract void ConvertFromEntity<T>(T entity);
public abstract T ConvertToEntity<T>();
}
and the following in the derived class:
protected override void ConvertFromEntity<T>(T entity) where T:DocNum
{
throw new NotImplementedException();
}
but now the error given is Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly
Can any one help me implement this solution so that the DTODocNum can compile whilst referring to the entity type?

Move the type parameter to the class level and add a constraint:
public abstract class BaseDTO<T> where T : BaseEntity
{
protected abstract void ConvertFromEntity(T entity);
public abstract T ConvertToEntity();
}
public class DTODocNum : BaseDTO<DocNum> { ... }

Related

How To separate methods from my giant generic class

So I have a very big Generic class 1500+ rows and growing, with loads of methods. It has CrazyMethods and GoodMethods, I want to put the different kinds of methods in their own class but still be able to use my generic as if they were inside the generic class.
public class MyGeneric<T> : IMyGeneric<T> where T : IEntity
{
public MyGeneric(string stuff)
{
moreStuff(stuff);
}
// Region Good
public void MyGoodMethod1(T entity)
{
//does good stuff with the generic..
}
public T MyGoodMethod2()
{
//does other good stuff with the generic..
}
//Region Crazy
public void MyCrazyMethod1(T entity)
{
//does crazy stuff with the generic..
}
public T MyCrazyMethod2()
{
//does other crazy stuff with the generic..
}
}
Now in my other project where I use this generic it looks something like this
...
SomeObject _myObject = new MyGeneric<SomeObject>("ladida");
_myObject.MyGoodMethod1();
//..Other stuff
_myObject.MyCrazyMethod2();ยจ
...
How do I separate the methods from the MyGeneric class into separate classes (MyGenericGoodMethods.cs, MyGenericCrazyMethods.cs) but still be able to use them the way I showcased above ?
If I could use extension methods for generics that would be the perfect solution.
public static class MyGenericGoodMethods<T> where T : IEntity
{
public static T Method2(this MyGeneric<T> generic)
{
//does other good stuff with the generic..
}
}
but
Extension method can only be declared in non generic, non nested, static class
You can declare extension method in normal static class and use it with generic.
public static class MyGenericGoodMethodsExtensions
{
public static T Method2(this MyGeneric<T> generic)
{
//does other good stuff with the generic..
}
}
var myGeneric = new MyGeneric<string>();
myGeneric.Method2()
But you can always split your giant class in many separated generic classes and use them inside your main-generic class.
Split up your interfaces
public interface IMyGeneric<T>
{
void MyGeneric(string stuff);
}
public interface IMyGoodGeneric<T>
{
void MyGoodMethod1(T entity);
void MyGoodMethod2(T entity);
}
public interface IMyCrazyGeneric<T>
{
void MyCrazyMethod1(T entity);
void MyCrazyMethod2(T entity);
}
Introduce separated implementation
public class MyGeneric<T> : IMyGeneric<T> where T : IEntity
{
public void MyGeneric(string stuff)
{
// implementation
}
}
public class MyGoodGeneric<T> : IMyGoodGeneric<T> where T : IEntity
{
public void MyGoodMethod1(T entity) {}
public void MyGoodMethod2(T entity) {}
}
public class MyCrazyGeneric<T> : IMyCrazyGeneric<T> where T : IEntity
{
public void MyCrazyMethod1(T entity) {}
public void MyCrazyMethod2(T entity) {}
}
Then you can create your "giant" composition class which will implement all interfaces and use already existed implementations
public class MyGiantGeneric<T> : IMyGeneric<T>,
IMyGoodGeneric<T>,
IMyCrazyGeneric<T> where T : IEntity
{
private readonly IMyGeneric<T> _myGeneric;
private readonly IMyGoodGeneric<T> _myGoodGeneric;
private readonly IMyCrazyGeneric<T> _myCrazyGeneric;
public MyGiantGeneric(IMyGeneric<T> myGeneric,
IMyGoodGeneric<T> myGoodGeneric,
IMyGCrazyGeneric<T> myCrazyGeneric)
{
_myGeneric = myGeneric;
_myGoodGeneric = myGoodGeneric;
_myCrazyGeneric = myCrazyGeneric;
}
public void MyGeneric(string stuff)
{
_myGeneric.MyGeneric(stuff);
}
public void MyGoodMethod1(T entity)
{
_myGoodGeneric.MyGoodMethod1(entity);
}
// and so on...
}
With this approach your logic will stay in logically separated classes.
In case somewhere you need only MyGoodGeneric method you don't need to provide whole giant class and will provide only the part needed.
In case some where you want introduce another implementation only for the MyCrazy methods you will not be forced to implement MyGood methods which you don't need in this case.
Extension method can be generic, not its container class:
public static class Extensions
{
public static T Method2<T>(this MyGeneric<T> generic)
{
}
}
So Partial classes were exactly what i was looking for. Thanks to #BradleyDotNET and #AliAbdelfattah
public partial class MyGeneric<T> : IMyGeneric<T> where T : IEntity
{
public MyGeneric(string stuff)
{
moreStuff(stuff);
}
//.. other stuff
}
in MyGenericGood.cs
public partial class MyGeneric<T> where T : IEntity
{
public void MyGoodMethod1(T entity)
{
//does good stuff with the generic..
}
public T MyGoodMethod2()
{
//does other good stuff with the generic..
}
}

Overriding abstract method with generics

I have an abstract base class that is defined like this:
public abstract class MyBaseClass<T>
The class contains a definition for the method Get:
protected abstract MyBaseClass<T> Get(T id);
I create MyClass using MyBaseClass:
public class MyClass : MyBaseClass<string>
Now I have to implement Get, but don't know how to define it:
public override MyClass Get(object id)
or
public override MyClass Get(string id)
In both cases I will have to mention string as T and I would like to avoid it.
What is the correct way to override Get ?
Thank You.
When you stated the interface you were implementing you specified the generic argument as string when you wrote (: MyBaseClass<string>), as such the only way for you to implement the Get method is to use string in place of all values for T. If you want users of your class to be able to use other types then you need to make the implementing class generic as well:
public class MyClass<T> : MyBaseClass<T>
{
protected override MyBaseClass<T> Get(T id)
{
throw new NotImplementedException();
}
}
public abstract class MyBaseClass<T>
{
protected abstract MyBaseClass<T> Get(T id);
}
public class MyClass : MyBaseClass<string>
{
protected override MyBaseClass<string> Get(string id)
{
return FindById(id);//implement your logic
}
}
Implement abstaract class as follows:
public abstract class MyBaseClass<T>
{
protected abstract MyBaseClass<T> Get(T id);
protected abstract MyBaseClass<T> Get(string id);
}
And the extending class:
class Class1 : MyBaseClass<Object>
{
protected override MyBaseClass<object> Get(object id)
{
return (MyBaseClass<object>) id;
}
protected override MyBaseClass<object> Get(string id)
{
return FindMyBaseClass(id)
}
}

Control access to methods in base class, inherited from interface

I have a basic design consisting of the following classes and interfaces:
a IRepository<TEntity> interface,
a Repository<TEntity> base class,
and a concrete TenantRepository class.
The "problem"
Since everything inherited by the interface has public access by definition, I am allowed to call the Add method (base class)
_tenantRepository.Add(new Tenant { Name = "blah" } );
while I should be calling the Create method on TenantRepository
_tenantRepository.Create("blah");
The question
It would be nice if I was able to define the Add method as protected so that client code could not access the method, but that's not allowed due to the simple fact that it's a method defined in the interface and must have public access.
Alternatively I could name the methods identical so that I actually override the implementation in the concrete class. That would prevent the client code from calling the Repository.Add directly. But in some cases I really want to prevent client code from calling the method defined in the base class.
Another alternative could be to write something like this:
new protected void Add(Tenant tenant)
{
}
but that makes me shiver (and it will break soon enough when I start refactoring method names).
Is there a better way to achieve this?
Some code snippets as reference:
The interface:
public interface IRepository<TEntity> : IDisposable where TEntity : IEntity
{
IQueryable<TEntity> GetAll();
void Delete(TEntity entity);
void Add(TEntity entity);
}
A small portion of the base class:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
protected IDbContext Context;
public Repository(IDbContext context)
{
Context = context;
}
public void Add(TEntity entity)
{
DbSet.Add(entity);
}
// Left out other, for this question irrelevant, method implementations
}
And finally the TenantRepository
public class TenantRepository : Repository<Tenant>
{
public TenantRepository(IDbContext context)
: base(context)
{
}
public Tenant Create(string tenantName)
{
var tenant = new Tenant
{
Name = tenantName,
Guid = Guid.NewGuid().ToString()
};
if (Exists(tenant.Name))
{
throw new TenantAlreadyExistsException(tenant.Name);
}
Add(tenant);
return tenant;
}
// Left out other, for this question irrelevant, method implementations
}
One solution would be to make TenantRepository not inherit from your Repository. After all, it sounds like they have different functionality (you want to have Create instead of Add.)
If you go this route, Repository becomes a private member of your TenenantRepository class, as only it would know what repository methods should be called when.
You could hide the Add method using explicit interface implementation. Basically, in Repository, do this:
public IRepository<Tenant>.Add(Tenant toAdd)
{
//do the add
}
This they can only get by casting to an IRepository.
if in a TenantRepository you need Add to check for uniqueness of the Tenant, you should include that logic within the Add method itself.
You should make Add in your base Repository class virtual and override it in your TenantRepository so that it performs the uniqueness check you now have in your Create method.
public interface IRepository<T>
{
void Add(T entity);
}
public class Repository<T> : IRepository<T>
{
// mocking Add so it works without a DB
public virtual void Add(T entity)
{
Console.WriteLine("{0} added", entity.ToString());
}
}
public class Tenant
{
public string Name{get; private set;}
public Tenant(string Name)
{
this.Name=Name;
}
public override string ToString() {return this.Name;}
}
public class TenantRepository : Repository<Tenant>
{
// Add is virtual, so it can be overridden by TenantRepository
public override void Add(Tenant entity)
{
// this represents your uniqueness check
if(entity.Name=="Paolo") throw new Exception();
base.Add(entity); // calling Add on the base Repository
}
//you can now avoid having Create or making it just call Add
public Tenant Create(Tenant entity)
{
this.Add(entity);
return entity;
}
}

How to override parameter defined in interface method with richer type?

I have these:
public class TennisPlayer
{
}
public class RogerFederer : TennisPlayer
{
}
public class RafaelNadal : TennisPlayer
{
}
And then I have some classes with methods, like these:
public abstract class Manager
{
protected abstract void ScheduleFriendlies(TennisPlayer player);
}
public class RafaelNadalManager : Manager
{
public void ScheduleFriendlies(RafaelNadal rn)
{
//throw new NotClayException();
}
}
public class RogerFedererManager : Manager
{
public void ScheduleFriendlies(RogerFederer rf)
{
//throw new NotGrassException();
}
}
//'RafaelNadalManager' does not implement inherited abstract member 'Manager.ScheduleFriendlies(TennisPlayer)'
The thing I'm trying to achieve is that I would want to have child classes of Manager but every such class will be tied to one player and hence the methods in those child classes (Manager classes) will be specific to that player. In other words Roger should have his own ScheduleFriendlies while Rafael should have his own.
How do I go about this? Alternate designs would do, but keep in mind:
What I can alter: The inheritances, its routes etc
But do not have the luxury to: Take off child manager classes and merge into one (in other words, I need RogerFederer and RogerFedererManager as separate classes).
I tried this:
public abstract class Manager
{
protected abstract bool ScheduleFriendlies<T>(T player) where T : TennisPlayer;
}
public class RafaelNadalManager : Manager
{
protected override bool ScheduleFriendlies<T>(T player)
{
//but how do I enforce the caller that only RafaelNadal object can be
//passed to this but not RogerFederer?
}
}
You were close, but you need the class generic, not just the method:
public abstract class Manager<T> where T : TennisPlayer
{
protected abstract bool ScheduleFriendlies(T player);
}
You could then use:
public class RafaelNadalManager : Manager<RafaelNadal>
{
protected override bool ScheduleFriendlies(RafaelNadal player)
{}
}

abstract method in a virtual class

I have a c# Class that has lots of virtual methods, some of these methods are essentially abstract ( they are fully implemented in subclasses and the base class is empty).
To get it to compile i am throwing an InvalidOperationException in the base class with a comment on what should be done. This just feels dirty.
Is there a better way to design my classes?
edit:
It is for the middle tier of an application that will be ran in canada, half of the methods are generic hence the virtual. and half of the methods are province specific.
Public class PersonComponent()
{
public GetPersonById(Guid id) {
//Code to get person - same for all provinces
}
Public virtual DeletePerson(Guid id) {
//Common code
}
Public virtual UpdatePerson(Person p) {
throw new InvalidOperation("I wanna be abstract");
}
Public Class ABPersonComponent : PersonComponent
{
public override DeletePerson(Guid id)
{
//alberta specific delete code
}
public override UpdatePerson(Person p)
{
//alberta specific update codecode
}
}
hope this makes sense
Mark the base class as abstract, as well as the methods that have no implementation.
Like so
public abstract class BaseClass
{
public abstract void AbstractMethod();
}
public class SubClass: BaseClass
{
public override void AbstractMethod()
{
//Do Something
}
}
You can't have abstract methods outside of an abstract class. Marking a class as abstract means you won't be able to instantiate it. But then it doesn't make any sense to. What are you going to do with a class that doesn't implement the methods anyway?
Edit: From looking at your class, yeah I'd make PersonComponent abstract along with the UpdatePerson method. Either that, or if UpdatePerson just doesn't do anything for a PersonComponent keep it as is, but make the UpdatePerson method empty for PersonComponent.
Think about your object hierarchy. Do you want to share common code for all your derived classes, then implement base functionality in the base class.
When having shared base code, please notice the Template pattern. Use a public method and chain it to a protected virtual method with the core/shared implementation. End the shared implementation methodname with "Core".
For example:
public abstract class BaseClass
{
protected virtual void DeletePersonCore(Guid id)
{
//shared code
}
public void DeletePerson(Guid id)
{
//chain it to the core
DeletePersonCore(id);
}
}
public class DerivedClass : BaseClass
{
protected override void DeletePersonCore(Guid id)
{
//do some polymorphistic stuff
base.DeletePersonCore(id);
}
}
public class UsageClass
{
public void Delete()
{
DerivedClass dc = new DerivedClass();
dc.DeletePerson(Guid.NewGuid());
}
}

Categories