Invoking C# base class extension methods from inside derived class? - c#

This is a contrived example:
public static class MyExtensions
{
public static void MyMethod( this MyInterface obj, string txt )
{
}
}
interface MyInterface {}
public MyDerived : MyInterface
{
void DoStuff()
{
MyMethod( "test" ); // fails; compiler can't find MyMethod?
}
}
In my example above, I'm trying to call an extension method assigned to an interface from my derived class. The compiler fails here and says that MyMethod does not exist in the current context. I have all the appropriate using statements in my CS file, so I'm not sure what is going on.

Try invoking it like this:
this.MyMethod("test");

Here is alternate solution (preferred by me):
(this as MyInterface).MyMethod("test");
Why? - because the solution provided previously will not work in cases when extension method calls class's "new" method (property is a method too). In such cases you may intend to call an extension method on the type declared by the base class/interface, which might behave differently from the derived class/interface.
Also, this solution will work for both "new" and "override" methods, because virtual "override" will anyway invoke derived version, which would be also intended.
EDIT: this may be irrelevant if you don't really want to pass "base" to the extension method and instead allow it take "this". However, you must consider behavioral differences.
Also, interesting to note as an answer to the comment by Darin Dimitrov: extension methods don't require instance to run them, because they are static methods. You can invoke an extension method as static by passing parameters to it. However, "base" is not a valid parameter value for parameter marked with "this" in the extension method declaration, which (if I were MS), would allow to simplify general usage of extension methods.

Try calling it this way instead:
this.MyMethod("test");

Change the call to
this.MyMethod("test")
This code compiles:
public static class MyExtensions
{
public static void MyMethod( this MyInterface obj, string txt )
{
}
}
public interface MyInterface {}
public class MyDerived : MyInterface
{
void DoStuff()
{
this.MyMethod( "test" ); // works now
}
}

Related

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

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)

Is an Extension method similar to having "new" keyword method in c#?

Can we have some relation between extension methods and inheritance?
Or is an extension method similar to using the new-keyword in C#?
No to both questions. An extension method is actually a method that takes the object the extension operates on as first parameter.
The new keyword is used to allocate resources for an instance of a class. An extension method operates on an instance, but cannot act as a new-replacement, simply because it requires an instance (or null of that type) as a first parameter.
Consider:
public static class StringExtensions
{
public static string Reverse(this string _this)
{
// logic to reverse the string
}
}
You can call this static method in two ways:
// as an extension method:
string s = "hello world";
string t = s.Reverse();
// as a static method invocation:
string t = StringExtensions.Reverse(s);
In either case, the compiler changes the call in MSIL to map the second call. After compiling, there's no way you would recognize an extension method from it's static counterpart without the this-keyword.
To summarize
Extensions are not part of the class
Extensions have no relation to inheritance, in fact they are static methods, which are not inherited
Extensions cannot instantiate classes like the new keyword does (but inside the method you can of course instantiate classes).
Extension can operate on null, where otherwise a method of that class would raise a NullReferenceException. This follows from the fact that the instance is simply the first parameter in the static method.
It is possible to extend sealed classes (like string above), which is not possible through inheritance (you cannot derive from sealed classes).
EDIT:
Tigran and Floran hinted that this question is about the new modifier, and I added it might even be about the new generic constraint.
An extension method has no relation with either meaning of the new keyword. Here are, however, some thoughts in relation to each other. I hope it doesn't confuse matters more. If so, stick to the part above "EDIT" ;)
On the new modifier:
the new modifier is used to hide existing methods. An extension method can never hide existing methods, because the declaration is a static method. You will not even get a compile time warning or error when you do.
The new modifier requires that the method (or property) already exists and is accessible. An extension method can only work if the method with the same signature does not already exist.
The new modifier operates on an extension of the class through inheritance, i.e., every method is already inherited. An extension method operates on an instance of the class and has no inheritance relationship with the class.
On the new generic constraint:
the constraint limits the allowed generic types to those with an accessible parameterless constructor. An extension method has nothing to do with generics.
an extension method itself van be generic and the parameters (i.e., the allowed classes it operates on) can be limited by the new generic constraint:
// this ext. method will only operate on classes that inherit
// from ICollectible and have a public parameterless constructor
public static int CalculateTotal<T>(this T _collectible)
where T : ICollectible, new()
{
// calculate total
}
No, extension method simply extends the functionality of already existing class.
Extension methods enable you to "add" methods to existing types
without creating a new derived type, recompiling, or otherwise
modifying the original type.
See MSDN on Extension Methods (C# Programming Guide).
The new keyword is needed to allow you to override non-virtual and static methods from the base class.
public class A
{
public virtual void One();
public void Two();
}
public class B : A
{
public override void One();
public new void Two();
}
B b = new B();
A a = b as A;
a.One(); // Calls implementation in B
a.Two(); // Calls implementation in A
b.One(); // Calls implementation in B
b.Two(); // Calls implementation in B
Check out this link on new vs override.
No. An extension method is syntactic sugar for a separate, static class that takes, as its first argument, an object of the type that is being "extended." It isn't related to inheritance at all. The method only has access to the public members of the "extended" class, just like any other class would.
Extension methods are not related to inheritance or new keyword (or constructors). They allow for nicer code if you want to add some functionality to a class you do not have source code for. It also works if you do have the source code but then it is usually better to just change the source code.
For example you might like to be able to do this:
string text = "this is my string";
int count = text.WordCount();
This method does not exist in the String class and you need to do it like that:
string text = "this is my string";
int count = MyCommon.WordCount(text);
where WordCount() is a static method in some sort of common library of yours.
But with the extension methods you can also do this:
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
and then text.WordCount() will work just as if it was normal method defined in the String class. It just makes things a bit nicer to use.
Code taken from here which I suggest to read as well.

Two-step method resolution with inheritance and generic constraints

I've encountered something quite surprising when using generic constraints with inheritance. I have an overloaded methods Foo that differ with parameter - either base or derived class instance. In both cases it's generally just passing the instance to the second pair of overloaded methods - Bar.
When I call Foo with base class instance, Bar overload for the base class is called. When I call Foo with derived class instance, Bar overload for the derived class is called. This is clear and expected.
But when I tried to merge Foo methods into single one GenericFoo that use generics and constraints, methods are resolved differently - T is resolved correctly, but only base-class overload of Bar is called.
public class Animal { }
public class Cat : Animal { }
public class AnimalProcessor
{
public static void Foo(Animal obj)
{
Console.WriteLine("Foo(Animal)");
Bar(obj);
}
public static void Foo(Cat obj)
{
Console.WriteLine("Foo(Cat)");
Bar(obj);
}
// new generic method to replace the two above
public static void GenericFoo<T>(T obj)
where T : Animal
{
Console.WriteLine("Foo(generic)");
Bar(obj);
}
public static void Bar(Animal obj)
{
Console.WriteLine("Bar(Animal)");
}
public static void Bar(Cat obj)
{
Console.WriteLine("Bar(Cat)");
}
}
Testing code - two first cases for non-generic old methods, two last for new generic method.
Console.WriteLine("Animal()");
AnimalProcessor.Foo(new Animal());
Console.WriteLine();
Console.WriteLine("Cat()");
AnimalProcessor.Foo(new Cat());
Console.WriteLine();
Console.WriteLine("Animal()");
AnimalProcessor.GenericFoo(new Animal());
Console.WriteLine();
Console.WriteLine("Cat()");
AnimalProcessor.GenericFoo(new Cat());
Console.ReadLine();
And the result - note the difference in type resolved in Bar:
Animal()
Foo(Animal)
Bar(Animal)
Cat()
Foo(Cat)
Bar(Cat)
Animal()
Foo(generic)
Bar(Animal)
Cat()
Foo(generic)
Bar(Animal)
It looks like the compiler binds all calls from GenericFoo to the least specific overload, even if all more specific-typed calls are known at compile time. Why is that, what is the reason for such behaviour? Which part of specs defines this?
Per OP's request, comment re-posted as answer:
Generics are not templates. Generic methods are compiled once and their behavior is for the 'most generic' case (in this case, Animal.) This is different from C++ style templating, where the template is compiled separately for each specialization by type.
The generic C# method is compiled into a generic IL method. And in IL, you have to explicitly specify which overload you are calling. So there is no simple way how the compiler could have done this. (There is complicated way: run a mini-compiler that chooses the overload at this point dynamically, which is what dynamic does.)
If you want this behavior, one option would be to make Bar() a virtual method on Animal. Another option would be using dynamic.

MyClass equivalent in C#

In looking at this question, commenter #Jon Egerton mentioned that MyClass was a keyword in VB.Net. Having never used it, I went and found the documentation on it:
The MyClass keyword behaves like an object variable referring to the current instance of a class as originally implemented. MyClass is similar to Me, but all method calls on it are treated as if the method were NotOverridable.
I can see how that could kind of be useful, in some specific scenarios. What I can't think of is, how would you obtain the same behaviour in C# - that is, to ensure that a call to a virtual method myMethod is actually invoked against myMethod in the current class, and not a derived myMethod (a.k.a in the IL, invoking call rather than callvirt)?
I might just be having a complete mental blank moment though.
According to Jon Skeet, there is no such equivalent:
No, C# doesn't have an equivalent of VB.NET's MyClass keyword. If you want to guarantee not to call an overridden version of a method, you need to make it non-virtual in the first place.
An obvious workaround would be this:
public virtual void MyMethod()
{
MyLocalMethod();
}
private void MyLocalMethod()
{
...
}
Then you could call MyLocalMethod() when a VB user would write MyClass.MyMethod().
There is no C# equivalent of the MyClass keyword in VB.Net. To guarantee that an overridden version of a method will not be called, simply make it non-virtual.
In addition to answers saying it doesn't exist, so you have to make it non-virtual.
Here's a smelly (read: don't do this!) work-around. But seriously, re-think your design.
Basically move any method that must have the base one called into 'super'-base class, which sits above your existing base class. In your existing class call base.Method() to always call the non-overridden one.
void Main()
{
DerivedClass Instance = new DerivedClass();
Instance.MethodCaller();
}
class InternalBaseClass
{
public InternalBaseClass()
{
}
public virtual void Method()
{
Console.WriteLine("BASE METHOD");
}
}
class BaseClass : InternalBaseClass
{
public BaseClass()
{
}
public void MethodCaller()
{
base.Method();
}
}
class DerivedClass : BaseClass
{
public DerivedClass()
{
}
public override void Method()
{
Console.WriteLine("DERIVED METHOD");
}
}

Generic extension methods in C#: what will happen in this edge case?

In a recent question of mine I learned that if there are more than one extension methods with constraints that match the given type, the most specific one will be chosen. This got me thinking - how does the compiler determine which one is "more specific"? And what will the outcome be?
Let's say I have the following classes:
public MyClass : IComparable, IDisposable
{
// Implementation of members
}
public static class MyExtensions
{
public static void DoSomething<T>(this T item)
where T : IComparable
{ /* whatever */ }
public static void DoSomething<T>(this T item)
where T : IDisposable
{ /* whatever else */ }
}
If I now use the extension method as
var instance = new MyClass();
instance.DoSomething();
which method will be used? Or will the compiler throw an error?
Note: I'm not saying this is good design, or even that I have a case where I need to do this. But the term "more specific" was loose enough to make me ponder this, and now I have to know! :P
Update:
I guess I wasn't really as interested in what will happen in the above example, as in why. It came to my mind since I'd been doing stuff like
public static class CollectionExtensions
{
public static void DoSomething<T>(this T items) where T : IList { ... }
public static void DoSomething<T>(this T items) where T : IEnumerable { ... }
}
where the compiler knows to choose the first method for new List<Something>().DoSomething(), since it is "closer" to the type passed. What I was interested in then, was "what does closer in this context mean? How will the compiler react if the constraints are from two different inheritance chains? Why?"
The extensions class won't compile, in this case - you can't overload methods based solely on generic constraints.
If you put the two extension methods into different classes, then the calling code wouldn't compile - it would be an ambiguous call, as neither method would be "better" than the other... in both cases the generic type argument would be inferred as MyClass, so there'd just be two conversions from MyClass to MyClass, neither of which is better than the other.
This is basically just a special case of overloading, once you've found out that no instance methods are applicable. I wrote an article on overloading just recently which you may find useful - it doesn't call out this specific case, but it points to the relevant bits of the spec if you want to look in detail.
It will not compile at all and throw a compile time error saying call is ambiguish between the two methods.
Type 'MyExtensions' already defines a
member called 'DoSomething' with the
same parameter types.
EDIT
Here's why compiler gives such error. Extension methods are just syntactic sugars and all they do is bring fluency and readabilty on any type.
Check this code..
var instance = new MyClass();
instance.DoSomething();
Compiler replaces this code as following.
var instance = new MyClass();
MyExtensions.DoSomething(instance);
//Compiler gets confused. Which one to call IComparable or IDisposable
In your case compiler gets confused since there are two matching signatures to the method-call and it gives you the said error.
Generic constraints are not considered as part of method signature. These two methods are considered by compiler as ones with the same signature. So you will get compile error saying that method DoSomething is already defined.
public static void DoSomething<T>(this T item)
where T : IComparable
{ /* whatever */ }
public static void DoSomething<T>(this T item)
where T : IDisposable
{ /* whatever else */ }
Consider the following example:
class MyClass {}
static class MyClassExtensions
{
public static void DoSomething<T>(this T item, List<string> someList)
{
Console.WriteLine("Method with List in signature is called.");
}
public static void DoSomething<T>(this T item, IEnumerable<string> someEnumerable)
{
Console.WriteLine("Method with IEnumerable in signature is called.");
}
}
In this example, when testing with the following:
var myClass = new MyClass();
myClass.DoSomething(new List<string>());
The first method in the extensions class is called. In short, this means that the compiler determines the signature that is nearer the arguments passed, and employs that.

Categories

Resources