C# Method Overload and Extension Methods [duplicate] - c#

There have been occasions where I would want to override a method in a class with an extension method. Is there any way to do that in C#?
For example:
public static class StringExtension
{
public static int GetHashCode(this string inStr)
{
return MyHash(inStr);
}
}
A case where I've wanted to do this is to be able to store a hash of a string into a database and have that same value be used by all the classes that use the string class's hash (i.e. Dictionary, etc.) Since the built-in .NET hashing algorithm is not guaranteed to be compatible from one version of the framework to the next, I want to replace it with my own.
There are other cases I've run into where I'd want to override a class method with an extension method as well so it's not just specific to the string class or the GetHashCode method.
I know I could do this with subclassing off an existing class but it would be handy to be able to do it with an extension in a lot of cases.

No; an extension method never takes priority over an instance method with a suitable signature, and never participates in polymorphism (GetHashCode is a virtual method).

If the method has a different signature, then it can be done -- so in your case: no.
But otherwise you need to use inheritance to do what you are looking for.

As far as I know the answer is no, because an extension method is not an instance.It's more like an intellisense facility to me that let you call a static method using an instance of a class.
I think a solution to your problem can be an interceptor that intercepts the execution of a specific method (e.g. GetHashCode()) and do something else.To use such an interceptor (like the one Castle Project provides) all objects should be instansiated using an object factory (or an IoC container in Castle) so that thier interfaces can be intercepted through a dynamic proxy generated in runtime.(Caslte also lets you intercept virtual members of classes)

I have found a way to invoke an extension method with the same signature as a class method, however it does not seem very elegant. When playing around with extension methods I noticed some undocumented behavior. Sample code:
public static class TestableExtensions
{
public static string GetDesc(this ITestable ele)
{
return "Extension GetDesc";
}
public static void ValDesc(this ITestable ele, string choice)
{
if (choice == "ext def")
{
Console.WriteLine($"Base.Ext.Ext.GetDesc: {ele.GetDesc()}");
}
else if (choice == "ext base" && ele is BaseTest b)
{
Console.WriteLine($"Base.Ext.Base.GetDesc: {b.BaseFunc()}");
}
}
public static string ExtFunc(this ITestable ele)
{
return ele.GetDesc();
}
public static void ExtAction(this ITestable ele, string choice)
{
ele.ValDesc(choice);
}
}
public interface ITestable
{
}
public class BaseTest : ITestable
{
public string GetDesc()
{
return "Base GetDesc";
}
public void ValDesc(string choice)
{
if (choice == "")
{
Console.WriteLine($"Base.GetDesc: {GetDesc()}");
}
else if (choice == "ext")
{
Console.WriteLine($"Base.Ext.GetDesc: {this.ExtFunc()}");
}
else
{
this.ExtAction(choice);
}
}
public string BaseFunc()
{
return GetDesc();
}
}
What I noticed was that if I called a second method from inside an extension method, it would call the extension method that matched the signature even if there was a class method that also matched the signature. For example in the code above, when I call ExtFunc(), which in turn calls ele.GetDesc(), I get the return string "Extension GetDesc" instead of the string "Base GetDesc" that we would expect.
Testing the code:
var bt = new BaseTest();
bt.ValDesc("");
//Output is Base.GetDesc: Base GetDesc
bt.ValDesc("ext");
//Output is Base.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext def");
//Output is Base.Ext.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext base");
//Output is Base.Ext.Base.GetDesc: Base GetDesc
This allows you to bounce back and forth between class methods and extension methods at will, but requires the addition of duplicate "pass-through" methods to get you into the "scope" you desire. I am calling it scope here for lack of a better word. Hopefully someone can let me know what it is actually called.
You might have guessed by my "pass-through" method names that I also toyed with the idea of passing delegates to them in the hopes that a single method or two could act as a pass-through for multiple methods with the same signature. Unfortunately it was not to be as once the delegate was unpacked it always chose the class method over the extension method even from inside another extension method. "Scope" no longer mattered. I have not used Action and Func delegates very much though so maybe someone more experienced could figure that part out.

Related

Method overriding or interception

In my project, I have many DLL assemblies referenced. One of those DLL's contains the bool method that I want to change. I do not have the original source for the DLL and using a Reflector to decompile a project seems impractical. All I want to do is intercept or override this method or method call so that I can change it's return value to match my own method outside of said DLL.
Any such way to do this? Thanks!
Edit:
Here is an example:
public virtual bool isOwner()
{
return false;
}
Essentially, I just want to change getOwner to return true;
If the class is public and the method is marked as virtual, then you can simply override it with this syntax:
public MyClass : TheClass
{
public override ReturnType MethodName(Arguments)
{
//class the base class implementation if needed
//base.MethodName(Arguments)
//do your own stuff and return whatever is needed
}
}
Hope this helps
EDIT: A word of caution though, this won't replace the calling code within the DLL. It will only work if you instantiate the derived class yourself and call it from your code.
Is there a general way to do what you want, built into .NET?
Yes, and no.
If you want every usage of class X' method Y to be replaced by some other code, then no, there is nothing built into .NET class system or compiler that will do this.
If you can inherit from class X, overriding method Y, and then ensure that all places where class X is used, your new class is used instead, then yes, that is the proper way to do this.
This is easily done:
public class YourFixedClass : TheProblematicClass
{
public override string YourProblematicMethod()
{
// probably call the problematic method through base.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
Or, if you can make a new class that implements all the same interfaces, wrapping (delegating) all the methods and properties of the original (problematic) class, then that might be doable, but this requires all actual usage of the class to go through the interfaces.
As this:
public class Wrapper : IInterface1, IInterface2
{
private readonly YourProblematicClass _C;
public Wrapper(YourProblematicClass c)
{
_C = c;
}
public string YourProblematicMetho()
{
// probably call the problematic method through _C.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
If, on the other hand, you don't have control of where all the code is that calls the class/method, then no, you can't do any of this.
So what else is there? Well, there is always the debugger interfaces. You can make a program that is somehow the debugger of itself, patching in the right code upon demand, but this is likely to be extraordinary difficult to get right.
In short, no, there is no way to do what you want. You need to find a different way to accomplish this.
Have you thought about changing the original assembly in the first place? I understand that you don't have the source code for it, but is that because:
You lost it
You didn't make it
In point 1, I would really work towards recreating the source code, either through a decompiler or similar, and get a new project going to fix that.
In point 2, have you thought about contacting the people that made it and asking them for help?
Uhm Ok you can do something like this:
public class MyNameClass : MyDllname.MyClassName
{
public bool isOwner()
{
return !base.isOwner();
}
}
Then you have override the method and you can use all the other methods in the DLL simply using an istance(if there aren't static) of the MyNameClass
You can use "new" modifier.
See example on http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Or this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassA().IsEvenDayToday()); // Result: true
Console.WriteLine(new ClassB().IsEvenDayToday()); // Result: false
Console.ReadKey();
}
}
public class ClassA : ClassB
{
public new bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 == 0;
}
}
public class ClassB
{
public bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 != 0;
}
}

Why do we have to explicitly specify "this" when invoking an extension method from within a method of a class being extended?

public class StoreController : Controller
{
public string Index()
{
// implicitly specified instance does not work
//return GetMemberName();
// must specify this explicitly
return this.GetMemberName();
}
}
public static class Utilities
{
public static string GetMemberName(this Controller caller,
[CallerMemberName] string memberName = "")
{
return caller.GetType().FullName + "." + memberName;
}
}
Why do we have to explicitly specify this when invoking an extension method from within a method of a class being extended?
In my mental model, we usually can omit this such as when we initialize fields, for example.
An extension method is technically not a method attached to your class.
yourClass.ExtensionMethod() isn't the same as yourClass.ClassMethod().
Basically, what you are doing is getting a convenient way of doing this:
ExtensionMethod(YourClass yourClass) {
//do something
return yourClass;
}
That is my understanding of an extension method. It's a convenient way of calling a method against a class you can't change. So, that's why you can't just call it without this. It's not a class method.
Extension method is just a syntactic sugar to call a static method. Tthis line of code return this.GetMemberName(); is actually convert to a call to static method like Utilities.GetMemberName(this);
As you can see, you have to send this to the static method and that is the reason why you need this keyword.
Without being present at the design board meeting where this was decided it's hard to say why it's like that.
In this text I use method or instance method in the sense of a function associated with a specific object instance and I use function in a mathematical sense. A function receives a number of arguments and creates a result (which is potentially void)
If we do not consider virtual methods which are more complex because the actual function to be called is determined runtime then any and all method calls are syntactic sugar. If we have two methods defined below
internal static class Extensions {
public static string FooEx(this MyClass self){
return self.ToString();
}
}
internal class MyClass {
public string Bar(){
var s1 = Foo();
var s2 = this.FooEx();
}
private string Foo(){
return ToString();
}
}
Then both will be translated to a function call where the first (and only) argument in both cases will be the object identified by this. If you are doubtful about this then look at the IL produced for any call to an instance method and you will notice there's an extra argument compared to the declaration in code. This argument is the thisreference, which is always passed as the first argument to an instance method.
So in the case of an instance method the compiler still need to determine which object to pass as the first argument to the function. That is exactly the same it has to do if you are calling an extension method without this which also means that can't be the real reason why you have to use this in front of an extension method.
In the compiler for Marvin, a compiler build on top of the Mono compiler I had to do a similar trick as C# does with extension methods and wondered why the specs require the this
The real reason why the compiler enforces you to use this before an extension method is that the specs says so. What the reason behind that decision is would need the attention of some one like #EricLippert who where probably there when they decided on that requirement

Declare a function supporting both Void and IEnumerator

I was wondering if there is a way to declare a method (in an interface for example) that supports the use of IEnumerator and Void, without the need to implement both in the subclasses?
public void Start()
public IEnumerator Start()
this is related to my other question: Hold or Wait while Coroutine finishes
i noticed in the Unity context, the default Start() method seems to allow for both.
You can't do that because those methods would have the same signature and the CSC woudn't be able to figure out which method should be statically bound for each call. e.g.:
public class TestClass
{
public int FooMethod()
{
return 1;
}
public void FooMethod()
{
return;
}
public string FooMethod()
{
return "foo";
}
}
static void Main()
{
TestClass test = new TestClass();
Console.WriteLine(test.FooMethod()); // which FooMethod should be called here?
}
A method's return type is not considered as part of its signature. What you can do is overload the same method with a different signature to return a different type. Also, in the case of an additional method that differs only in returning void, you can always choose not to use the result returned by the original method.
The case with interfaces is similar. when a class implements an interface it is agreeing to a protocol, that it implements that interface's behaviour which is what consumers of your class expect. So you cannot partly agree with an interface. Although you can throw a NotImplementedException in your implementations you have to at least define all members, which leads to the same problem mentioned in the above example: the C# compiler will not be able to statically bind your method calls and your code will fail to compile.
You can solve your problem by reconsidering your design.
The short answer is no.
The closest you could get to this is using generics, however that would not work for a void, sorry.
public T Start()
One function name + combination of parameters can only be declared once, thus can only have one output.

C# virtual static method

Why is static virtual impossible? Is C# dependent or just don't have any sense in the OO world?
I know the concept has already been underlined but I did not find a simple answer to the previous question.
virtual means the method called will be chosen at run-time, depending on the dynamic type of the object. static means no object is necessary to call the method.
How do you propose to do both in the same method?
Eric Lippert has a blog post about this, and as usual with his posts, he covers the subject in great depth:
https://learn.microsoft.com/en-us/archive/blogs/ericlippert/calling-static-methods-on-type-parameters-is-illegal-part-one
“virtual” and “static” are opposites! “virtual” means “determine the method to be called based on run time type information”, and “static” means “determine the method to be called solely based on compile time static analysis”
The contradiction between "static" and "virtual" is only a C# problem. If "static" were replaced by "class level", like in many other languages, no one would be blindfolded.
Too bad the choice of words made C# crippled in this respect. It is still possible to call the Type.InvokeMember method to simulate a call to a class level, virtual method. You just have to pass the method name as a string. No compile time check, no strong typing and no control that subclasses implement the method.
Some Delphi beauty:
type
TFormClass = class of TForm;
var
formClass: TFormClass;
myForm: TForm;
begin
...
formClass = GetAnyFormClassYouWouldLike;
myForm = formClass.Create(nil);
myForm.Show;
end
Guys who say that there is no sense in static virtual methods - if you don't understand how this could be possible, it does not mean that it is impossible. There are languages that allow this!! Look at Delphi, for example.
I'm going to be the one who naysays. What you are describing is not technically part of the language. Sorry. But it is possible to simulate it within the language.
Let's consider what you're asking for - you want a collection of methods that aren't attached to any particular object that can all be easily callable and replaceable at run time or compile time.
To me that sounds like what you really want is a singleton object with delegated methods.
Let's put together an example:
public interface ICurrencyWriter {
string Write(int i);
string Write(float f);
}
public class DelegatedCurrencyWriter : ICurrencyWriter {
public DelegatedCurrencyWriter()
{
IntWriter = i => i.ToString();
FloatWriter = f => f.ToString();
}
public string Write(int i) { return IntWriter(i); }
public string Write(float f) { return FloatWriter(f); }
public Func<int, string> IntWriter { get; set; }
public Func<float, string> FloatWriter { get; set; }
}
public class SingletonCurrencyWriter {
public static DelegatedCurrencyWriter Writer {
get {
if (_writer == null)
_writer = new DelegatedCurrencyWriter();
return _writer;
}
}
}
in use:
Console.WriteLine(SingletonCurrencyWriter.Writer.Write(400.0f); // 400.0
SingletonCurrencyWriter.Writer.FloatWriter = f => String.Format("{0} bucks and {1} little pennies.", (int)f, (int)(f * 100));
Console.WriteLine(SingletonCurrencyWriter.Writer.Write(400.0f); // 400 bucks and 0 little pennies
Given all this, we now have a singleton class that writes out currency values and I can change the behavior of it. I've basically defined the behavior convention at compile time and can now change the behavior at either compile time (in the constructor) or run time, which is, I believe the effect you're trying to get. If you want inheritance of behavior, you can do that to by implementing back chaining (ie, have the new method call the previous one).
That said, I don't especially recommend the example code above. For one, it isn't thread safe and there really isn't a lot in place to keep life sane. Global dependence on this kind of structure means global instability. This is one of the many ways that changeable behavior was implemented in the dim dark days of C: structs of function pointers, and in this case a single global struct.
Yes it is possible.
The most wanted use case for that is to have factories which can be "overriden"
In order to do this, you will have to rely on generic type parameters using the F-bounded polymorphism.
Example 1
Let's take a factory example:
class A: { public static A Create(int number) { return ... ;} }
class B: A { /* How to override the static Create method to return B? */}
You also want createB to be accessible and returning B objects in the B class. Or you might like A's static functions to be a library that should be extensible by B. Solution:
class A<T> where T: A<T> { public static T Create(int number) { return ...; } }
class B: A<B> { /* no create function */ }
B theb = B.Create(2); // Perfectly fine.
A thea = A.Create(0); // Here as well
Example 2 (advanced):
Let's define a static function to multiply matrices of values.
public abstract class Value<T> where T : Value<T> {
//This method is static but by subclassing T we can use virtual methods.
public static Matrix<T> MultiplyMatrix(Matrix<T> m1, Matrix<T> m2) {
return // Code to multiply two matrices using add and multiply;
}
public abstract T multiply(T other);
public abstract T add(T other);
public abstract T opposed();
public T minus(T other) {
return this.add(other.opposed());
}
}
// Abstract override
public abstract class Number<T> : Value<T> where T: Number<T> {
protected double real;
/// Note: The use of MultiplyMatrix returns a Matrix of Number here.
public Matrix<T> timesVector(List<T> vector) {
return MultiplyMatrix(new Matrix<T>() {this as T}, new Matrix<T>(vector));
}
}
public class ComplexNumber : Number<ComplexNumber> {
protected double imag;
/// Note: The use of MultiplyMatrix returns a Matrix of ComplexNumber here.
}
Now you can also use the static MultiplyMatrix method to return a matrix of complex numbers directly from ComplexNumber
Matrix<ComplexNumber> result = ComplexNumber.MultiplyMatrix(matrix1, matrix2);
While technically it's not possible to define a static virtual method, for all the reasons already pointed out here, you can functionally accomplish what I think you're trying using C# extension methods.
From Microsoft Docs:
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
Check out Extension Methods (C# Programming Guide) for more details.
In .NET, virtual method dispatch is (roughly) done by looking at the actual type of an object when the method is called at runtime, and finding the most overriding method from the class's vtable. When calling on a static class, there is no object instance to check, and so no vtable to do the lookup on.
To summarize all the options presented:
This is not a part of C# because in it, static means "not bound to anything at runtime" as it has ever since C (and maybe earlier). static entities are bound to the declaring type (thus are able to access its other static entities), but only at compile time.
This is possible in other languages where a static equivalent (if needed at all) means "bound to a type object at runtime" instead. Examples include Delphi, Python, PHP.
This can be emulated in a number of ways which can be classified as:
Use runtime binding
Static methods with a singleton object or lookalike
Virtual method that returns the same for all instances
Redefined in a derived type to return a different result (constant or derived from static members of the redefining type)
Retrieves the type object from the instance
Use compile-time binding
Use a template that modifies the code for each derived type to access the same-named entities of that type, e.g. with the CRTP
The 2022+ answer, if you are running .Net 7 or above, is that now static virtual members is now supported in interfaces. Technically it's static abstract instead of "static virtual" but the effect is that same. Standard static methods signatures can be defined in an interface and implemented statically.
Here are a few examples on the usage and syntax in .Net 7

How can I create Prototype Methods (like JavaScript) in C#.Net?

How is it possible to make prototype methods in C#.Net?
In JavaScript, I can do the following to create a trim method for the string object:
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
How can I go about doing this in C#.Net?
You can't dynamically add methods to existing objects or classes in .NET, except by changing the source for that class.
You can, however, in C# 3.0, use extension methods, which look like new methods, but are compile-time magic.
To do this for your code:
public static class StringExtensions
{
public static String trim(this String s)
{
return s.Trim();
}
}
To use it:
String s = " Test ";
s = s.trim();
This looks like a new method, but will compile the exact same way as this code:
String s = " Test ";
s = StringExtensions.trim(s);
What exactly are you trying to accomplish? Perhaps there are better ways of doing what you want?
It sounds like you're talking about C#'s Extension Methods. You add functionality to existing classes by inserting the "this" keyword before the first parameter. The method has to be a static method in a static class. Strings in .NET already have a "Trim" method, so I'll use another example.
public static class MyStringEtensions
{
public static bool ContainsMabster(this string s)
{
return s.Contains("Mabster");
}
}
So now every string has a tremendously useful ContainsMabster method, which I can use like this:
if ("Why hello there, Mabster!".ContainsMabster()) { /* ... */ }
Note that you can also add extension methods to interfaces (eg IList), which means that any class implementing that interface will also pick up that new method.
Any extra parameters you declare in the extension method (after the first "this" parameter) are treated as normal parameters.
You need to create an extension method, which requires .NET 3.5. The method needs to be static, in a static class. The first parameter of the method needs to be prefixed with "this" in the signature.
public static string MyMethod(this string input)
{
// do things
}
You can then call it like
"asdfas".MyMethod();
Using the 3.5 compiler you can use an Extension Method:
public static void Trim(this string s)
{
// implementation
}
You can use this on a CLR 2.0 targeted project (3.5 compiler) by including this hack:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
public sealed class ExtensionAttribute : Attribute
{
}
}

Categories