Why calling method on interface uses base implementation instead of override? - c#

I have a problem with my code.
I would expect that since I'm constructing the Implementation object; every time I call Method() I'd use actual Implementation.Method() and not it's abstract's Base.Method(). It does not seem reasonable that I have to downcast to actual implementer or specify interface explicitly (So interfaces are not transitive in C#? I will call the "first proper instance of interface implementer" and not my class?)
I have a structure similar to this (simplified for clarity):
https://dotnetfiddle.net/oYVlQO
using System;
public interface IBase
{
string Method();
}
public abstract class Base : IBase
{
public string Method() { return "Sample"; }
}
public class Implementation : Base // if I add ", IBase" to this it works as expected, but why?
{
new public string Method() { return "Overriden"; }
}
public class Program
{
// and it's used like so...
public static void Main()
{
IBase b = new Implementation();
//Implementation b = new Implementation(); // It works as expected, always using Implementation.Method();
Console.WriteLine(b.Method()); // Produces "Sample", so Base.Method(). Why not implementation?
Console.WriteLine(((Implementation) b).Method()); // Produces "Overriden", so Implementation.Method(); Since when I have to downcast to use overriden method!?
}
}
}
I'm really scratching my head over this; Especially that the same code in Java works "as I would expect" https://repl.it/repls/VitalSpiritedWebpage
I've tried to find it in the c# specs to no avail, maybe I do not have the proper keywords...

In cause of the question, which is:
Why is it that way?
My answer:
Because you don’t override the method but hide it.
The interface is implemented by the baseclass, so the Method is called on the base-class.
To answer the question, which isn’t asked:
How would it work?
Answer:
using System;
public interface IBase
{
string Method();
}
public abstract class Base : IBase
{
public virtual string Method() { return "Sample"; }
}
public class Implementation : Base
{
public override string Method() { return "Overriden"; }
}

You may want to take a look at the part of the C# spec that deals with interface re-implementation.
When you access a member through the interface, it begins its lookup at the most derived type that explicitly implements that interface. In your example, the most derived type is Base and so it calls the method that's present there.
When you added IBase to the list of interfaces explicitly implemented by Implementation it worked, because that's the new starting point for lookup and it finds your new method.
You can either solve your problem by making the base member virtual and then overriding it in derived classes, or you can re-implement the interface by including that in the list for your Implementation class.

So the problem in my sample code is two-fold.
I assumed that in C# methods are "virtual" by default (as is in Java). Since I'm usually coding in Java, I've made an incorrect assumption.
See Is it possible to override a non-virtual method?
If I'd use virtual, I could override the method and achieve exactly the output I expected, as described in doc:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/virtual namely "When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member."
My code, hovewer, is using method hiding, so unless I inform the compiler about my intention of using my implementation, it'll default to non-hidden method (as resolved by abstract class being the actual, original implementer)

Related

How to define virtual method with return type which is not void in C#

This might sound like a dumb question, but I need to write a virtual method that is being overridden by inherited class. I don't need the virtual method to have any code, since this method is fully dependent on inherited class, therefore all code will be in the override methods.
However, the method has a return type that is not void. If I keep the virtual method empty it would give me an error "no all path return a value".
The only solution I came up with was to implement the virtual method with returning a dummy empty string, but I don't feel this is the best way. Is there any other way to define a virtual method with return type?
Edit:
Even most answers were correct in their own way, they did not help in my case, therefore I am adding snippets of the code which shows why I need to create instance of the base class, and why I can't use interface, or abstract:
//base class
public class Parser
{
public virtual string GetTitle()
{
return "";
}
}
//sub class
public class XYZSite : Parser
{
public override string GetTitle()
{
//do something
return title;
}
}
// in my code I am trying to create a dynamic object
Parser siteObj = new Parser();
string site = "xyz";
switch (site)
{
case "abc":
feedUrl = "www.abc.com/rss";
siteObj = new ABCSite();
break;
case "xyz":
feedUrl = "www.xzy.com/rss";
siteObj = new XYZSite();
break;
}
//further work with siteObj, this is why I wanted to initialize it with base class,
//therefore it won't break no matter what inherited class it was
siteObj.GetTitle();
I know the way I cast Parser object to Site object doesn't seem very optimal, but this is the only way it worked for me, so Please feel free to correct any thing you find wrong in my code.
Edit (Solution)
I followed the advice of many of replies by using interface and abstract. However it only worked for me when I changed the base class to abstract along with all its methods, and inherited the base class from the interface, and then inherited the sub classes from the base class. That way only I could make sure that all classes have the same methods, which can help me generate variant object in runtime.
Public interface IParser
{
string GetTitle();
}
Public abstract class Parser : IParser
{
public abstract string GetTitle();
}
Public class XYZ : Parser
{
public string GetTitle();
{
//actual get title code goes here
}
}
//in my web form I declare the object as follows
IParser siteObj = null;
...
//depending on a certain condition I cast the object to specific sub class
siteObj = new XYZ();
...
//only now I can use GetTitle method regardless of type of object
siteObj.GetTitle();
I am giving the credit to CarbineCoder since he was the one who put enough effort to take me the closest to the right solution. Yet I thank everyone for the contribution.
You can throw NotImplementedException instead of returning object:
public virtual object Method()
{
throw new NotImplementedException();
}
But if you are not implementing anything in virtual method you can create abstract instead of virtual:
public abstract object Method();
Edit:
Another option is to create interface for it.
public interface IMethods
{
object Method();
}
And make your classes children of this interface.
you need to use abstract here. The abstract modifier indicates that the thing being modified has a missing or incomplete implementation.
public abstract returntype MethodName();
But as you say, 'since this method is fully dependent on inherited class, therefore all code will be in the override methods', than if you are really going to override the functionality of the method in inherited class, why do you care if the method returns dummy or stuff? (e.g: you can make it virtual and get going)
Edit: as you cannot mark class as abstract, you can use virtual method instead.
public virtual returntype MethodName()
{
.....
return xyz;
}
(just for info: An abstract member is implicitly virtual. and abstract is sort of pure virtual. so you need virtual, instead of pure virtual)
Since other answers have discussed about abstract/virtual implementation, I am suggesting my own version.
There is a contradiction in your requirement.
You want a base class which is not an abstract but it has a method which is not implemented. Don't you think this unimplemented method will make the class incomplete and end up making it an abstract one even though you haven't explicitly said so?
So lets assume your class will never be an abstract class and its perfectly reasonable to have it as a normal class. Does it make sense to remove this method from the class altogether and move it to an interface?
Can you try extracting this method and put it into an interface.
interface NewInterface
{
string NewMethod();
}
public BaseClass
{
...
}
public DerivedClass : BaseClass, NewInterface
{
public string NewMethod
{
...
}
}
If you can do this, then you need not have to worry about the base class being abstract/ having NotImplemented exception, only downside is every derived class should implement this interface, but thats the point of making the base class non-abstract.
I don't see any problem in implementing Abstract BaseClass/ Interface for your approach. Both are supposed to be the solution for your problem.
//Parser siteObj = new Parser(); - Dont initialize it here,
//your are initializing it once more below
NewIterface siteObj;
string site = "xyz";
switch (site)
{
case "abc":
feedUrl = "www.abc.com/rss";
siteObj = new ABCSite();
break;
case "xyz":
feedUrl = "www.xzy.com/rss";
siteObj = new XYZSite();
break;
}

How to tell if MemberInfo represents an override

Given the following code:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public override void Method() { }
}
...
var baseMethodInfo = typeof(Base).GetMember("Method")[0];
var derivedMethodInfo = typeof(Derived).GetMember("Method")[0];
Is it possible to determine if the derivedMethodInfo represents a method declaration which overrides another in a base class?
In another question it was observed that had Method been declared abstract (and not implemented) in the base class, derivedMethodInfo.DeclaringType would have turned up as Base, which makes sense after reading #EricLippert's comments. I noticed that in the present example, since the derived class re-declares the method, that derivedMethodInfo.DeclaringType == derivedMethodInfo.ReflectedType, viz. Derived.
There doesn't seem to be any connection between baseMethodInfo and derivedMethodInfo, other than their names are the same and their respective declaring types appear in the same inheritance chain. Is there any better way to make the connection?
The reason I ask is that there appears to be no way to distinguish, through reflection, between the earlier example and the following one:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public new void Method() { }
}
In this case as well, the Derived class both declares and reflects a member called Method.
A method shadowing a virtual method will have the VtableLayoutMask flag set in Attributes.
Note that an ordinary virtual method (with no similar name from a base type) will also have this flag set.
This flag appears to indicate that the method introduces a new entry in the VTable.
There's a more specific class MethodInfo which derives from MemberInfo. Note that not all kinds of members can be virtual (fields cannot, for example).
If you say
var derivedMethodInfo = typeof(Derived).GetMethod("Method");
then you can check if
derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo
or not. See documentation for GetBaseDefinition() where they also have a code example.

Is it a acceptable to hide a property in a derived interface which returns a derived type?

TL;DR
What is wrong with hiding a property in an interface so that I can change its declaration to return a derived type of the original property?
I'm sure this must have been asked before, but I can't find it, and apologies for the long question.
Say I have this situation:
public interface A
{
B TheB{get;}
}
public interface MoreSpecificA : A
{
MoreSpecificB TheMoreSpecificB{get;}
}
public interface B{...}
public interface MoreSpecificB:B{...}
I would like users of MoreSpecificA to be able to get at the B which is a MoreSpecificB. They could do this by calling TheB and cast it, or they could call the method TheMoreSpecificB. I could also declare MoreSpecificA like so:
public interface MoreSpecificA : A
{
new MoreSpecificB TheB{get;}
}
so that now they can just use the same method and get back a MoreSpecificB.
Using the new to hide a method puts my teeth on edge, so why is this a bad idea? It seems like a reasonable thing to do here.
The general suggestion in most cases I have seen for this seems to be to use generics instead, but this seems to have a problem in that if I have a MoreSpecificA and I want to return it in a method that declares the return type as A then I have to have MoreSpecificA extend A which gives ambiguity when accessing TheB on the MoreSpecificA instance as it doesn't know if you want A.TheB or MoreSpecificA.TheB
public interface ABase<T> where T : B
{
T TheB{get;}
}
public interface A : ABase<B>
{
}
public interface MoreSpecificA : ABase<MoreSpecificB>,A
{
}
public class blah
{
public A GetA(MoreSpecificA specificA)
{
return specificA; //can't do this unless MoreSpecificA extends A
}
public B GetB(MoreSpecificA specificA)
{
return specificA.TheB; //compiler complains about ambiguity here, if MoreSpcificA extends A
}
}
which could be solved by declaring a new TheB on MoreSpecificA (but the new issue again).
If MoreSpecificA doesn't extend A then the first method in the class blah above complains as now as MoreSpcificA can't be converted to A.
Whilst writing this I have noticed that if I declare my BaseA to be contravariant like this:
public interface ABase<out T> where T : B
{
T TheB{get;}
}
and my class to be
public class blah
{
public ABase<B> GetA(MoreSpecificA specificA)
{
return specificA;
}
public B GetB(MoreSpecificA specificA)
{
return specificA.TheB; //compiler complains about ambiguity here
}
}
Then I get the best of both worlds. Does the applicability of this solution depend on whether A adds anything to ABase?
Or is my original plan of just hiding the method in the derived type to return a derived type of the original method ok?
Or is my original plan of just hiding the method in the derived type to return a derived type of the original method ok?
So long as it means exactly the same thing, I think it's okay. You can see something like this in the standard libraries, with IDbConnection.CreateCommand (which returns IDbCommand) and SqlConnection.CreateCommand (which returns SqlCommand) for example.
In that case it's using explicit interface implementation for the IDbConnection version, but it's the same principle.
You can also see it in IEnumerator<T>.Current vs IEnumerator.Current and IEnumerable<T>.GetEnumerator() vs IEnumerable.GetEnumerator().
I would only use it in cases where the implementation for the more weakly-typed method just returns the result of calling the more strongly-typed method though, use implicit conversion. When they actually start doing different things, that becomes much harder to reason about later.

Force the use of interface instead of concrete implementation in declaration (.NET)

In C++, you can do the following:
class base_class
{
public:
virtual void do_something() = 0;
};
class derived_class : public base_class
{
private:
virtual void do_something()
{
std::cout << "do_something() called";
}
};
The derived_class overrides the method do_something() and makes it private. The effect is, that the only way to call this method is like this:
base_class *object = new derived_class();
object->do_something();
If you declare the object as of type derived_class, you can't call the method because it's private:
derived_class *object = new derived_class();
object->do_something();
// --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class'
I think this is quite nice, because if you create an abstract class that is used as an interface, you can make sure that nobody accidentally declares a field as the concrete type, but always uses the interface class.
Since in C# / .NET in general, you aren't allowed to narrow the access from public to private when overriding a method, is there a way to achieve a similar effect here?
If you explicitly implement an interface, this will at least encourage people to use the interface type in the declaration.
interface IMyInterface
{
void MyMethod();
}
class MyImplementation : IMyInterface
{
void IMyInterface.MyMethod()
{
}
}
One will only see MyMethod after casting the instance to IMyInterface. If the declaration uses the interface type, there is no casting needed in subsequent uses.
MSDN page on explicit interface implementation (thanks Luke, saves me a few seconds^^)
IMyInterface instance = new MyImplementation();
instance.MyMethod();
MyImplementation instance2 = new MyImplementation();
instance2.MyMethod(); // Won't compile with an explicit implementation
((IMyInterface)instance2).MyMethod();
You can do this in the .Net world too, using explicit interface implementation
As an example, BindingList<T> implements IBindingList, but you have to cast it to IBindingList to see the method.
You are able to decrease a method's availability by marking it as new.
The example from MSDN's CA2222: Do not decrease inherited member visibility:
using System;
namespace UsageLibrary
{
public class ABaseType
{
public void BasePublicMethod(int argument1) {}
}
public class ADerivedType:ABaseType
{
// Violates rule: DoNotDecreaseInheritedMemberVisibility.
// The compiler returns an error if this is overridden instead of new.
private new void BasePublicMethod(int argument1){}
}
}
This is really more interesting as an academic exercise; if your code is truly dependent on not being able to call BasePublicMethod on ADerivedType, that's a warning sign of a dubious design.
The problem with this strategy, should it be implemented, is that the method is not truly private. If you were to upcast a reference to base_class, then the method is now public. Since it's a virtual method, user code will execute derived_class::do_something() eventhough it's marked as private.

What are some real-world examples of abstract new/virtual/override/abstract keywords?

I'm moving from PHP to C#.
In PHP it was simple and straightforward to use abstract classes to create a "cascading override" pattern, basically "the base class method will take care of it unless the inheriting class has a method with the same signature".
In C#, however, I just spent about 20 minutes trying out various combinations of the keywords new, virtual, abstract, and override in the base and inheriting classes until I finally got the right combination which does this simple cascading override pattern.
So even those the code below works the way I want it, these added keywords suggest to me that C# can do much more with abstract classes. I've looked up examples of these keywords and understand basically what they do, but still can't imagine a real scenario in which I would use them other than this simple "cascading override" pattern. What are some real world ways that you implement these keywords in your day-to-day programming?
code that works:
using System;
namespace TestOverride23433
{
public class Program
{
static void Main(string[] args)
{
string[] dataTypeIdCodes = { "line", "wn" };
for (int index = 0; index < dataTypeIdCodes.Length; index++)
{
DataType dataType = DataType.Create(dataTypeIdCodes[index]);
Console.WriteLine(dataType.GetBuildItemBlock());
}
Console.ReadLine();
}
}
public abstract class DataType
{
public static DataType Create(string dataTypeIdCode)
{
switch (dataTypeIdCode)
{
case "line":
return new DataTypeLine();
case "wn":
return new DataTypeWholeNumber();
default:
return null;
}
}
//must be defined as virtual
public virtual string GetBuildItemBlock()
{
return "GetBuildItemBlock executed in the default datatype class";
}
}
public class DataTypeLine : DataType
{
public DataTypeLine()
{
Console.WriteLine("DataTypeLine just created.");
}
}
public class DataTypeWholeNumber : DataType
{
public DataTypeWholeNumber()
{
Console.WriteLine("DataTypeWholeNumber just created.");
}
//new public override string GetBuildItemBlock() //base method is erroneously executed
//public override string GetBuildItemBlock() //gets error "cannot override inherited member because it is not marked virtual, abstract, or override"
public override string GetBuildItemBlock()
{
return "GetBuildItemBlock executed in the WHOLENUMBER class.";
}
}
}
virtual/override is the core polymorphism pair; sounds like you've already cracked these
abstract is like virtual, but there is no sensible base implementation; use-cases: perhaps a Stream, where it is necessary for the actual implementation to do something with the bytes. This forces the class to be abstract
new should usually be avoided; it breaks polymorphism... the most common case is to re-expose with a more specific signature / return-type (perhaps in a sealed class, since it doesn't get prettier up the chain...) - see SqlConnection.CreateCommand (vs DbConnection.CreateCommand), or (perhaps more notably) IEnumerator<T>.Current (vs IEnumerator.Current)
It appears you have already figured out virtual and override from your example, so:
'abstract' can also be applied on members instead of 'virtual', in which case you do not specify an implementation for the method (';' directly after the signature). This forces all concrete descendants to implement the method.
'new' has nothing to do with inheritance, but can instead be used in a descendant class on a member to hide a member in the base class that has the exact same signature.
In a nutshell ;)
Further to the other answers.
Overrride for when you wish to allow child classes to perform their own processing, no processing or even just call the parent class processing for a function. An override or virtual function does not have to be implemented in descendent classes.
Abstract when you don't wish to perform any processing in your base class but want that method to be implemented by any inheriting class. (Best when the inheriting class behaviour can differ drastically). If a class contains nothing but abstract methods then it is effectively an interface type. A function specified as abstract MUST be implemented in the child class (the compiler will throw an error if not).

Categories

Resources