C# class using subclass does not implement inherited abstract member error - c#

Here's the c# code I'm trying to compile
Fairly simple, testDMO that inherits from testDMOBase
Then test that inherits from testBase
public abstract class testDMOBase { }
public class testDMO : testDMOBase { }
public abstract class testBase
{
abstract protected void LoadCRUD(testDMOBase dmo);
}
public class test : testBase
{
override protected void LoadCRUD(testDMO dmo) { }
}
I'm getting the following errors:
'test' does not implement inherited abstract member
'testBase.LoadCRUD(testDMOBase)' 'test.LoadCRUD(testDMO)': no suitable
method found to override
Shouldn't the use of a subclass be ok on the override method?

Shouldn't the use of a subclass be ok on the override method?
No. Aside from anything else, which implementation would you expect to be called if the caller provided an instance other than your subclass?
testBase t = new test();
t.LoadCRUD(new SomeOtherDMO()); // What would be called here?
You might well argue that it would make sense to be able to override the base method with a subclass method which is more general (e.g. with a parameter which is a superclass of the original parameter type, or with a return type which is a subclass of the original return type) but .NET doesn't allow either of these anyway. The parameter and return types of the overriding method have to match the original method exactly, at least after generic type parameter substitution.
It sounds like you may want to make your base type generic:
public abstract class TestBase<T> where T : TestDmoBase
{
public abstract void LoadCrud(T dmo);
}
public class Test : TestBase<TestDmo>
{
public override void LoadCrud(TestDmo dmo)
{
...
}
}
Note that you should follow .NET naming conventions, too - even in sample code.

No, in this case you have to exactly follow the signature of the abstract method, in order to provide valid override.
So, you have to write:
public class test : testBase
{
override protected void LoadCRUD(testDMOBase dmo) //BASE CLASS
{ }
}

Shouldn't the use of a subclass be ok on the override method?
No, method overrides must use the same parameter types as their original declarations.

Related

ClassName<Type> or ClassName<Object> for abstract base class

I'm relatively newbie to C# programming. I want to create Abstract Base Class that contains a few of abstract, and virtual methods.
By the following two examples, what are their differences of usage and which is more commonly used?
Example-1, use Type keyword.
public abstract class DecoratorBase<Type> : ValidatableBindableBase
{
public virtual void SetFields(Type T) { }
public virtual void SetFieldsBack(ref Type T) { }
}
Example-2, use Object keyword.
public abstract class DecoratorBase<Object> : ValidatableBindableBase
{
public virtual void SetFields(Object T) { }
public virtual void SetFieldsBack(ref Object T) { }
}
In my case, Type or Object will represent my business model POCO class.
Sorry, if this question sound so naive to you. Thanks.
Please, don't do that!
It looks like you're a little confused about generics. When you define a generic abstract type (using < and > after the name), you're telling the compiler "I will give you some type, but I don't know which type just now. Use the name I'm giving you as a placeholder for the type later." The convention is to use the upper case T.
For example, the following defines a generic abstract class.
public abstract class SomeClass<T> {}
Later, when we create a derived class, we create it with a type:
public class ConcreteClass : SomeClass<int> {}
If we had methods declared in our abstract class that used the type T, our new ConcreteClass would replace references to T with int. So in your case, you should do:
public abstract class DecoratorBase<T> : ValidatableBindableBase
{
public virtual void SetFields(T param) { }
public virtual void SetFieldsBack(ref T param) { }
}
You can see here, T represents the unknown type as T, instead of naming the type Type and the parameter T. What you were doing is known as 'hiding', that is, When you use Type or Object in the way you were doing, it is assigning a new meaning to those words. You should absolutely avoid hiding in this way.
Now if you create a concrete class, say:
public class Decorator : DecoratorBase<Control>
{
public override SetFields(Control param) {}
}
You have type safety: the parameter now has to be a Control, at least for this concrete implementation. You can define other implementations with different types, and inherit the same base methods.
See this question for a simple understanding of how to use generics.

Preventing a method from being overridden in C#

How do I prevent a method from being overridden in a derived class?
In Java I could do this by using the final modifier on the method I wish to prevent from being overridden.
How do I achieve the same in C#?
I am aware of using sealed but apparently I can use it only with the override keyword?
class A
{
public void methodA()
{
// Code.
}
public virtual void methodB()
{
// Code.
}
}
class B : A
{
sealed override public void methodB()
{
// Code.
}
}
So in the above example I can prevent the methodB() from being overridden by any classes deriving from class B, but how do I prevent class B from overriding the methodB() in the first place?
Update: I missed the virtual keyword in the methodB() declaration on class A when i posted this question. Corrected it.
You don't need to do anything. The virtual modifier specifies that a method can be overridden. Omitting it means that the method is 'final'.
Specifically, a method must be virtual, abstract, or override for it to be overridden.
Using the new keyword will allow the base class method to be hidden, but it will still not override it i.e. when you call A.methodB() you will get the base class version, but if you call B.methodB() you will get the new version.
As you mentioned, you can prevent further overriding of MethodB in class B by using sealed with override
class B : A
{
public sealed override void methodB()
{
Console.WriteLine("Class C cannot override this method now");
}
}
Use of the sealed modifier along with override prevents a derived class from further overriding the method.
If you do not want methodB in class A to be overridden by any child classes, do not mark that method virtual. Simply remove it. virtual keyword enable the method to be overridden in child classes
public void methodA()
{
}
Use sealed keyword on your classes to prevent further overriding of the class
In C#, a function not marked virtual (which also includes overrides of virtual functions) is effectively sealed and cannot be overridden. So, your example code actually won't compile because the override keyword is not valid unless there is a method marked virtual with the same signature in a base class.
If A.methodB() were marked virtual, then you could override the method from A, but prevent it being further overridden in classes deriving more indirectly, using the sealed keyword exactly as you have shown.
One thing to keep in mind is that while method overriding can be prevented, method hiding cannot. Given your current definition of class A, the following definition of class B is legal and there's nothing you can do about it:
class B:A
{
public new void methodB()
{
//code
}
}
The new keyword basically "breaks" the inheritance/overriding hierarchy as it pertains to this one method; any reference to a class B, treated as a class B (or any further derived type) will use the implementation from class B and ignore the one from class A unless B's implementation specifically calls back to it. However, if you were to treat an instance of class B as a class A (by casting it or passing it as a parameter), then the "new" implementation is ignored.
This differs from overriding, where a class B that is being treated as a class A and truly overrides a virtual methodB would still use class B's override of the method. Also understand that method hiding is inferred (though you will get a compiler warning); if you declare a method with the same signature in a derived class and do not specify either new or override, the base class method will be hidden.
In a base class, the sealed keyword is only used to prevent a class from being derived, but in inherited classes it can be used to prevent another inherited class from overriding the method.
To prevent a base class method from being overridden, just do not specify it as virtual. In the example you provided, class B could not override methodB because methodB was not marked as virtual on the original class.
this will compile:
class A
{
public virtual void methodA()
{
//code
}
public virtual void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
this will not:
class A
{
public void methodA()
{
//code
}
public void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
EDITTED: clarified and corrected my original statement about the sealed keyword

C# Virtual & Override Keywords

I thought I had this nailed, and then I go and look at some source at work and am left wondering why there are so many contradictions in what I read from msdn and what I am seeing in source....
My understanding is that the virtual keyword can be used in method declarations to allow any deriving classes to override it.
The override keyword would then need to be used in the derived class when implementing the superclass' virtual method....
For example:
public abstract class A
{
public virtual string GetName();
}
public class B:A
{
//assume there are some defined properties.
public override string GetName()
{
return FirstName;
}
}
I have a few questions:
1) Is it really necessary to define a method as virtual if it has no implementation? Surely it can just be overwritten in the subclass without the use of virtual and override?
2) If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
EDIT:
You're right my code will not compile... I want to know why....I uinderstand your answers but then I saw this:
public abstract class RequestHandler<TRequest, TResponse> : RequestHandler, IRequestHandler<TRequest>, IRequestHandler, IDisposable, ITypedRequestHandler
where TRequest : global::Agatha.Common.Request
where TResponse : global::Agatha.Common.Response, new()
{
protected RequestHandler();
public virtual void AfterHandle(TRequest request);
public virtual void BeforeHandle(TRequest request);
public override Response CreateDefaultResponse();
public TResponse CreateTypedResponse();
public override Response Handle(Request request);
public abstract Response Handle(TRequest request);
}
The above doesnt cause the compiler to complain...
Firstly the above code is invalid. A virtual method still has to have a body with a default implementation. to do what you have done above you would need to use the abstract keyaord instead of virtual.
abstract means that there is no method body provided but that any class deriving from it must implement this method (unless it is abstract too).
I think this pretty much answers your questions....
If it has no implementation then it cannot be virtual, it must be abstract. If it has an implementation that just does nothing then that must be implemented.
The whole point of a virtual class is that it has default behaviour so you can choose whether or not to override it. If it were abstract then you would have to override it (unless you were deriving another abstract class).
Is it really necessary to define a method as virtual if it has no implementation?
You can make the method abstract (it will implicitly make it virtual).
Surely it can just be overwritten in the subclass without the use of virtual and override?
If you just "overwrite" it without explicitly overriding it, it won't be the same method, and calling the method on a variable of the base class won't call the derived method (it won't participate in polymorphism). You would just be "hiding" the method of the base class (the compiler actually warns you about this, if it's really what you want to do you must use the new modifier.)
An example will make it clearer:
class B
{
public virtual void M() { Console.WriteLine("B.M") };
}
class D1 : Base
{
// Hides the base method
public new void M() { Console.WriteLine("D1.M") };
}
class D2 : Base
{
// Overrides the base method
public override void M() { Console.WriteLine("D2.M") };
}
...
D1 d1 = new D1();
d1.M(); // Prints "D1.M"
B b1 = d1;
b1.M(); // Prints "B.M", because D1.M doesn't override B.M
D2 d2 = new D1();
d2.M(); // Prints "D2.M"
B b2 = d2;
b2.M(); // Also prints "D2.M", because D2.M overrides B.M
If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
No, only if it's abstract... a virtual method can have an implementation, and in that case derived classes are not forced to override it.
1) Is it really necessary to define a method as virtual if it has no implementation? Surely it can just be overwritten in the subclass without the use of virtual and override?
As said in other answers, virtual methods need to have implementations. You are confusing it with abstract.
If you were asking whether virtual methods which do have an implementation need to be declared virtual: In C#, yes, it is necessary. In Java, you can override any old method. It was a C# design decision to require overriding to be specifically allowed with the virtual keyword, so that methods cannot be overridden unless intended by the programmer.
If the programmer has not expressed intent by not using virtual, you can still "override" methods, with the new keyword. However, this works a bit differently. Hopefully this code will help illustrate the concept:
class Program
{
static void Main(string[] args)
{
var baseC = new BaseClass();
var extC = new ExtClass();
var lazyC = new LazyClass();
Console.WriteLine(baseC.NewMethod());
Console.WriteLine(baseC.VirtualOverrideMethod());
Console.WriteLine("---");
Console.WriteLine(extC.NewMethod());
Console.WriteLine(extC.VirtualOverrideMethod());
Console.WriteLine("---");
Console.WriteLine(((BaseClass) extC).NewMethod());
Console.WriteLine(((BaseClass) extC).VirtualOverrideMethod()); // Redundant typecast
Console.WriteLine("---");
Console.WriteLine(lazyC.VirtualOverrideMethod());
Console.ReadKey();
}
public class BaseClass
{
public BaseClass()
{
}
public string NewMethod()
{
return "NewMethod of BaseClass";
}
public virtual string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of BaseClass";
}
}
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
class LazyClass : BaseClass
{
}
}
Output:
NewMethod of BaseClass
VirtualOverrideMethod of BaseClass
---
NewMethod of ExtClass
VirtualOverrideMethod of ExtClass
---
NewMethod of BaseClass
VirtualOverrideMethod of ExtClass
---
VirtualOverrideMethod of BaseClass
2) If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
Not at all. virtual is a way of saying, "it's okay if you want to override this method". In fact, I included LazyClass in my code above to show this.
The above doesnt cause the compiler to complain...
I haven't used interfaces much, but that looks like one. In my code, if I change
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
to:
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
I get:
error CS0501: 'OverrideTest.Program.ExtClass.VirtualOverrideMethod()' must declare a body because it is not marked abstract, extern, or partial
From Visual Studio 2010. The same goes for the virtual method of my BaseClass.
The need for virtual is dictated by polymorphism. Think about what happens when you redefine a method in a subclass using new:
class Parent
{
void Foo() { Console.WriteLine("Parent"); }
virtual void Bar { Console.WriteLine("Parent"); }
}
class Child : Parent
{
new void Foo() { Console.WriteLine("Child"); } // another method Foo
override void Bar { Console.WriteLine("Child"); }
}
var child = new Child(); // a Child instance
var parent = (Parent)child; // same object, but statically typed as Parent
c.Bar(); // prints "Child"
p.Bar(); // again, prints "Child" -- expected virtual behavior
c.Foo(); // prints "Child"
p.Foo(); // but this prints "Parent"!!
For this reason, classes that are intended to be derived from (i.e. not sealed) should always mark the methods that can be overridden as virtual -- otherwise there will be confusing runtime behavior like above. There's no difference if the parent implementation actually does anything or not; the point is that it behaves differently.
ok, by declaring the method as virtual (and not wishing to override the method in the subclass), you'd be entering the world of method hiding if you were to introduce a method with the same name into the subclass. You have to define it as thus:
public abstract class A
{
public virtual string GetName()
{
return null;
}
}
public class B : A
{
//assume there are some defined properties.
public new string GetName()
{
return FirstName;
}
}
I'd recommend that you think of the abstract override approach:
public abstract class A
{
public abstract string GetName()
}
// to override
public class B : A
{
//assume there are some defined properties.
public override string GetName()
{
return FirstName;
}
}
this would be quite different. I would strongly recommend that you just override the abstract method in the subclass.
However, here's a quick ref on the subject (old but a good read):
http://www.akadia.com/services/dotnet_polymorphism.html
1) Is it really necessary to define a method as virtual if it has no
implementation? Surely it can just be overwritten in the subclass
without the use of virtual and override?
You can use an abstract methods, that have no body, but they if you derive from that class you must to override that method. All abstact methods have to be overriden in child class.
2) If (1) is incorrect, am I right in thinking that every virtual
method must be overridden in the subclass using it....
No, instead, you can use a virtual keyword to have an implementation inside that, but do not making override in a child class mandatory. Gives you more flexibility, from that point of view.
Usauly they use abstract to create rigid constrains for childs, so every child derived from it must implement specified member of base class.
That's exactly the difference between a virtual and an abstract method:
A virtual method can be overridden by derived classes if the choose to. A virtual method may or may not have a default implementation for inheritors to call into, which is done using the base keyword.
An abstract method must be overridden by derived classes. Its constraints are:
It can only be defined in an abstract class.
It cannot have an implementation, since it's up to the inheritors to define its behavior.

Run same method in base and derived class

What do I need to do to first run the method in the base class then run the same method in the derived class? Is this a good idea?
I want run common actions in base class and extend it in the derived class in the same method. Is this how it is usually done?
public abstract class MyBase
{
void DoStuff()
{
//some common implementation
}
}
public class MyDerived : MyBase
{
void DoStuff()
{
// DoStuff in the base first
// Then DoStuff in here
}
}
are you talking about something like that?
class base
{
protected virtual void method()
{
// do some stuff in base class, something common for all derived classes
}
}
class derived : base
{
public override void method()
{
base.method(); // call method from base
// do here some more work related to this instance of object
}
}
that's not a bad idea, I do use it a lot when I have some common functionality for all derived classes.
If you want to guarantee that the base class logic is run (and not rely on the derived class being polite), you can do this:
public void Method()
{
//Stuff that should always happen in base class
OnMethod();
}
protected virtual void OnMethod()
{
//Default base class implementation that derived class can either override or extend
}
Use base.TheMethod() to run a method in the base class from a derived class.
If you want to run a method of a derived class from a base class, then you have to cast the base class to the derived class. This means that your class needs to be aware of who is deriving it, which breaks encapsulation and should be avoided.

Sealing an interface after implementing it

I am working on a small project and I came across that problem.
The project output is a library containing an interface. I would like to implement that interface and seal the functions in it like this if possible:
public interface ITest
{
void SomeMethod();
}
class A : ITest
{
public sealed override SomeMethod()
{
}
}
The idea is to have the interface available to everyone and have some specialized class that implements it. The exception is that I want to make sure that if someone create a specialized class of type A, he/she won't be able to change the method's behavior.
The problem is you can't put the "override" keyword in there since the method isn't declared as "virtual" in the interface. And you can't declare it as "virtual" in the interface since it's not allowed. And you can't remove the "override" keyword since it's needed by "sealed".
Any workaround or brainstorming idea would be welcome, but if someone can come up with a solution that includes an interface, I'd be really happy to learn it!
Thanks!
EDIT: Forget this question! Like Ani said, I forgot that by default method in C# are sealed. Seems like it's always good to go back to the basics once in a while...
I may have completely misunderstood the question, but if your intention is to seal the method in A, you can just do:
class A : ITest
{
public void SomeMethod() { ... }
}
Unlike Java, methods in C# are sealed by default. Subclasses of A won't be able to override the method since it hasn't been marked virtual.
On the other hand, if your intention is to mark the method 'almost sealed' in the interface, so that it forces upon an implementing class to immediately seal it, that isn't possible. It isn't (and shouldn't be) the business of the interface to dictate such details of implementation - an interface is meant to represent a specification.
Use an abstract base class with internal visibility. This base class is not visible outside of the library but allows you to seal the method and the class still implements the interface.
public interface ITest
{
void SomeMethod();
}
internal abstract class SuperA : ITest
{
public abstract void SomeMethod();
}
class A : SuperA
{
public sealed override void SomeMethod()
{
}
}
Your understanding of sealed keyword is incorrect. As a method modifier, sealed is used to prevent a virtual method(defined in the base class) to be override in the next generation of derived classes. For example:
class Base
{
public virtual void M() { }
}
class Derived : Base
{
public sealed override void M() { }
}
class A : Derived
{
public override void M() { } //compile error, M is sealed in Derived
}
Developers can always use new modifier to define a method with the same name in the derived class, that hides the one defined in the base class.
if someone create a specialized class
of type A, he/she won't be able to
change the method's behavior.
If "specialized class" means a class derived from A, the answer is: he can always hide the method in A, but he can't change the method's behavior.
Why not use an abstract class like below.
Haven't tested it but this should work?
public abstract class Test
{
public virtual void SomeMethod() {}
//OR
public abstract void SomeMethod();//MSDN says:
//an abstract method is implicitly virtual
}
class A : Test
{
public sealed override SomeMethod()
{
}
}
Methods in C# are sealed by default.. Here is a sample
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.SomeMethod();
b ss = new b();
ss.SomeMethod();
Console.ReadLine();
}
}
public interface ITest { void SomeMethod(); }
class A : ITest { public void SomeMethod() {
Console.WriteLine("SomeMethod Called from Class A object");
} }
class b : A
{
//public override void SomeMethod()
//{
// Console.WriteLine("Called from Class B Object");
//}
}

Categories

Resources