Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# ASP.NET MVC Inheritance , +
public class SomeRepository<TContext> : IDisposable
            where TContext : DbContext, new()
        {
            protected TContext context;
            protected SomeRepository()
            { }
 
        public virtual void Create<T>(T item) where T : class, new()
        {
            ...
        }
        }
 
    internal class SomeCrud : SomeRepository<SomeContext>
    {
        public override void Create(ConcreteType item)
        {
            ....
        }
    }
}
Hello I have base class like SomeRepository with four standart methods.Each one this method can work with different types.That works good.
But I got a situation that I need to add some instruction to one of those methods in derived class.That's why I signed like virtual in base class and tried to override one of this method with concrete type and I got a error
not suitable method found to override on deriveed overriden method please help me!
Posted 19-Jun-12 10:39am
Comments
Wes Aday at 19-Jun-12 15:58pm
   
public override void Create<T>(T item) { base.Create<T>(item); }
thomas_wingfield at 19-Jun-12 16:04pm
   
Wes Aday. If I want that derived Create methd should seems on Create in base class, but with one different instruction in derived method.If I would call base
I can't add this instruction.I need Create method with own logic in derived class without logic of base class method
Karthik. A at 19-Jun-12 16:06pm
   
Exactly, Wes Aday and my answer's are just stubs. You just have to remove the call base.Create(item) and add your own implementation.
Wes Aday at 19-Jun-12 16:09pm
   
That make absolutely no sense at all. Are you overriding Create or not?
thomas_wingfield at 19-Jun-12 16:16pm
   
Yes I'm overriding but it should seems to Create of base class but a little bit another
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

This is something which could called generic specialization, by the analogy with C++ template specialization.
 
It looks like your efforts are useless until you work with generic methods; it is not possible to specialize the implementation via overriding for a concrete type. I want to give you an alternative idea: move a generic parameter from a method to a type. Just think about it:
 
class Base<T> {
    internal protected virtual void Create(T item) { /*...*/ } // maybe, pseudo-abstract
} //class Base<T>

struct ConcreteType {/*...*/}
 
//this is something you really can do
class Derived : Base<ConcreteType> {
    internal protected override void Create(ConcreteType item) { /*...*/ }
} //class Derived
 
Pretty similar to what you wanted, but in this way it can work.
 
More typically, the first method would be abstract:
abstract class Base<T> {
    internal protected abstract void Create(T item)
} //class Base<T>

class Derived : Base<ConcreteType> {
    internal protected override void Create(ConcreteType item) { /*...*/ }
} //class Derived
 
Note that you don't have to specialize all the generic parameters in the derived type, but still can override the method with a specialized generic parameter; this is how to do it:
abstract class Base<SomeType, ParameterType> {
    internal protected abstract void Create(ParameterType item);
    // use SomeType in some other way
} //class Base<T>

class Derived<SomeType> : Base<SomeType, ConcreteType> { //second generic parameter "specialized out"
    internal protected override void Create(ConcreteType item) { /*...*/ }
    // use SomeType in some other way
} //class Derived
 
Are you getting it? This way you can get yourself enough flexibility which could suit your goals. Again, think about it.
 
—SA
  Permalink  
v4
Comments
thomas_wingfield at 20-Jun-12 12:05pm
   
Sergey Alexandrovich Kryukov thanks a lot for your help.Actually I decided how do it, but I will try your solution
Sergey Alexandrovich Kryukov at 21-Jun-12 11:22am
   
You are very welcome.
This is just one of the possible ideas.
As you seem to see some reason in it, please also accept it formally (green button) -- thanks.
--SA
A_K_ at 30-Jun-12 0:52am
   
My +5. Good answer as always..
Sergey Alexandrovich Kryukov at 30-Jun-12 1:54am
   
Thank you, A K.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

That's because the signature of the Create method is wrong. Change it to the following
 
    internal class SomeCrud : SomeRepository<SomeContext>
    {
        public override void Create<T>(T item)
        {
            base.Create<T>(item);
        }
    }
 
Shortcut to do this is, in the SomeCrud class, enter override first, then give a space. Now you will get a list of items that can be overridden. Just choose one, you will get the stub w/ a call to the base class's method.
 
Hope this helps!
  Permalink  
Comments
thomas_wingfield at 19-Jun-12 15:57pm
   
Sorry but it doesn't help.But thanks for post
Karthik. A at 19-Jun-12 16:03pm
   
Sorry about that. But are you saying you get an error if you do this? You cannot just override a generic method with a concrete type, if you are trying to achieve something in the effect of what you have posted. Can you pls. elaborate your issue?
Wes Aday at 19-Jun-12 16:03pm
   
What do you mean "it doesn't help"?
thomas_wingfield at 19-Jun-12 16:05pm
   
check my comment for my question
Karthik. A at 19-Jun-12 16:06pm
   
Pls. check my reply for your comment.
thomas_wingfield at 19-Jun-12 16:13pm
   
My reply:)
I have logic that adds a Something to database in Create method of base class(Just simple crud).In derived class when I add class I have to attach some another class.Check my source code:
public virtual void Create(T item) where T : class, new()
{
DbSet set = GetDbSet(typeof(T)).GetValue(context, null) as DbSet;
using (context)
{
set.Add(item);
Save(context);
}
}
That works good
But like this no:
public override void Create(Product item)
{
DbSet<Product> set = GetDbSet(typeof(Product)).GetValue(context, null) as DbSet<Product>;
DbSet set1 = GetDbSet(typeof(User)).GetValue(context, null) as DbSet;
using (context)
{
set1.Attach(item.User);
set.Add(item);
Save(context);
}
}
Karthik. A at 19-Jun-12 16:20pm
   
This is not an override at all. Any override to Create must also be generic. Once you start having concrete item, there is no point overriding.
thomas_wingfield at 19-Jun-12 16:15pm
   
I tried like this:
If i changed signature Product on T I can't see User property, If I change like
override void Create<Product>(Product item) my IntelSense can't see Product like a type.
Karthik. A at 19-Jun-12 16:22pm
   
You are totally missing the point - an override of a constrained method should also be constrained. Only when you call this method, you get to pass a concrete type. Like, instance.Create<Product>(product);
thomas_wingfield at 19-Jun-12 16:22pm
   
Can u provide some example?How I will see in item.User if it will be a T?
Karthik. A at 19-Jun-12 16:26pm
   
You could have 2 constraints and have the method in the base class itself. Like this:
 
public virtual void Create<t,>(T tItem, U uItem)
where T : class, new()
where U : class, new()
{
throw new NotImplementedException();
}
 
Now you can attach the 2nd item and add the 1st item.
thomas_wingfield at 19-Jun-12 16:29pm
   
Yes but if I will be use Signature generic like u said I can't see User in item
Yes I did it like u said with base Create method, but how I can do with derived?
Karthik. A at 19-Jun-12 16:31pm
   
You don't even need the derived class, if you have this method in the base class, isn't it?
thomas_wingfield at 19-Jun-12 16:30pm
   
I tried with a 2 constraints but it not comfortable.
Karthik. A at 19-Jun-12 16:31pm
   
Not sure what you mean by that... what's not comfortable?
thomas_wingfield at 19-Jun-12 16:40pm
   
Karthik I'm very tahnkfull for your help man.But I have to use only one type constriaint in method.
Look I tried right now this:
internal class ProductCrud : AuctionRepository where T : Product
public override void Create(T item){}
 
That's helped me right now with error
But I'm new in programming with EF and WCF.I have a question.
new ProductCrud().Create(some).It' not bad architecture?Van I resolve it on ur opinion?
Karthik. A at 19-Jun-12 16:47pm
   
You are welcome! I wouldn't say it's bad. But if it seems like you are doing the same for various other types (w/ nested types), I would advice having a generic method w/ 2 constraints. Because now you have tied the concrete type to your repository which is not that best method to do this in my opinion. As you are saying that you cannot have multiple constraints, I cannot think of any other better way right away.
thomas_wingfield at 19-Jun-12 17:00pm
   
any way thanks a lot, if it will be bad idea I will try again with 2 constraints.
Did u mean add second constraint to AuctionRepository like class?
Karthik. A at 19-Jun-12 17:06pm
   
You're welcome and no, I meant adding a constraint to the Create method - T and U, as I mentioned in an earlier comment.
thomas_wingfield at 19-Jun-12 17:05pm
   
that was a bad solution, didn't help:(
Karthik. A at 19-Jun-12 17:07pm
   
Then, I would definitely advice using 2 constraints.
Sergey Alexandrovich Kryukov at 19-Jun-12 17:43pm
   
Those were correct explanations and arguments, but don't you think there should be some positive solution? The idea would be to modify the approach, but not giving up using OOP with the generic. I voted 4.
 
Want to see what's my idea? Please see my answer.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 406
1 Marcin Kozub 225
2 Sergey Alexandrovich Kryukov 205
3 Raul Iloc 170
4 Maciej Los 164
0 OriginalGriff 8,289
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,624
3 Maciej Los 4,989
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 29 Jun 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100