how to reference the Type in the Concrete class of a generic class
I found the following example, to which I have a follow up question.
stack overflow question
the existing code from the question is
public interface IRepository<T> where T : EntityObject
{
RepositoryInstructionResult Add(T item);
RepositoryInstructionResult Update(T item);
RepositoryInstructionResult Delete(T item);
}
public class Repository<T> : IRepository<T> where T : EntityObject
{
virtual RepositoryInstructionResult Add(T item)
{ //implementation}
virtual RepositoryInstructionResult Update(T item);
{ //implementation}
virtual RepositoryInstructionResult Delete(T item);
{ //implementation}
}
public class BarRepository : Repositorybase<Bar>
{
public override RepositoryInstructionResult Update(Bar item);
{
//Call base method if needed
//Base.Update(item);
//implement your custom logic here
}
}
what I would like to do is change the Update method to something like
public class BarRepository : Repositorybase<Bar>
{
// T is of Type Bar
public override RepositoryInstructionResult Update(T item);
{
//implement your custom logic here
}
}
Question: is there a way to expose the generic type in BarResposity : Repositorybase<Bar>
to the methods in BarRepository?
looking for a better alternative to "search and replace" when building out the concrete class (eg make a copy of BarRespository as FooRepository and change all references from Bar to Foo). I would rather change the type in one place only.
(edit) Usage needs to remain as
var obj = new BarRepository();
Solution 1:
Just as a note, if you're going to override all Add/Update/Delete anyways, you can make them as abstract in the RepositoryBase and then the vs suggestion is your friend:
and if there is shared logic between all of concrete classes you can put it in the abstract class and override abstract protected methods instead.
edit: op asked for code that can do it.. well this should work.. but if you want a new concrete implementation, you'll have to create 2 classes now
public class BarRepository<T> : RepositoryBase<T> where T : Bar
{
public override int Add(T item)
{
throw new NotImplementedException();
}
public override int Update(T item)
{
throw new NotImplementedException();
}
public override int Delete(T item)
{
throw new NotImplementedException();
}
}
public class BarRepository : BarRepository<Bar>
{
}
also, if classes are so similar that copy-paste and replace is enough, maybe logic shouldn't be in separate classes but in the generic class? could you give an example of 2 classes maybe?
edit 2: another dirty trick would be to use lambdas, though personally I don't know if I would do it:
public abstract class RepositoryBase<T>
{
public Func<T, int> Add { get; protected set; }
public Func<T, int> Update { get; protected set; }
public Func<T, int> Delete { get; protected set; }
}
public class BarRepository : RepositoryBase<Bar>
{
public BarRepository()
{
Add = i => 6;
Update = i => 7;
Delete = i => 8;
}
}