Hallo I would like to create an extension method for Char class that works as Char.IsDigit() method (but that will of course recognize a differnt type of characters).
I wrote this:
namespace CharExtensions
{
public static class CompilerCharExtension
{
public static Boolean IsAddOp(this Char c)
{
return c.Equals('+') || c.Equals('-');
}
}
}
that works fine but that it's not exactly what I meant.
This extension should be used this way:
using CharExtensions;
char x:
...
if(x.IsAddOp())
Console.WriteLine("Add op found");
While I would something like this:
using CharExtensions;
char x;
...
if(Char.IsAddOp(x))
Console.WriteLine("Add op found");
Thanks to everyone who could help me.
You cannot do that, as extension methods will always require an instance of the object.
See here
Extension methods are defined as static methods but are called by using instance method syntax.
Your question mention to fire a static method of a class. You actually want to define a static method for Char class, not add a extension to char instance. to define a static method you must access the original class something like
class SomeClass {
public int InstanceMethod() { return 1; }
public static int StaticMethod() { return 42; }
}
Now you can use StaticMethod as:
SomeClass.StaticMethod();
Then you must access to Microsoft .net framework code to add IsAddOp(x) method to Char class. Actually your way to define a extension with that one you say in question is wrong.. you dont try to define Extension method..you try to define Static method.
Related
Here's the method I would like to add:
private string S(int i){
return i == 1 ? "": "s";
}
I would like it so I can use it in any part of the application. But where should I add this and how can I make it so it's accessible everywhere?
This, in fact, would be an int extension method. It needs to be static; also, in order for it to be accessible everywhere, it needs to be public. Extension methods need to be defined in a static class, and they should contain the keyword this before the first argument, which would be indicating the type to extend. So the final approach would be:
namespace YourNameSpace
{
public static class Int32Extensions
{
public static string S(this int i)
{
return i == 1 ? "" : "s";
}
}
}
To use it somewhere else, you need to use the namespace in your subject code file
using YourNameSpace;
And simply call it
int i = 3;
string str = i.S(); //equals "s"
The method that you are showing is not an extension method. An extension method would (for instance) be this:
public static class MyStringExtensions
{
public static string S(this string text, int i)
{
return i == 1 ? "" : text;
}
}
The method has to be static, must be in a static class, and the first parameter must have the keyword this before declaration.
Put the class into the base of your namespace, so that you will automatically be able to access it from anywhere without having to specify the namespace with using.
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.
I want to, for example, add a method to integer (i.e., Int32), which will make me able to do the following:
int myInt = 32;
myInt.HelloWorld();
One can say, instead of insisting doing the above, you can write a method which takes an integer, HelloWorld(integer), like the following, more easily:
int myInt = 32;
HelloWorld(myInt);
However, I'm just curious whether it's possible or not. If true, is that a good programming practice to add some other functionality to well known classes?
PS: I tried to make another class which inherits from Int32, but cannot derive from sealed type 'int'.
You can add an extension method for int32.
public static class Int32Extensions
{
public static void HelloWorld(this int value)
{
// do something
}
}
Just remember to using the namespace the class is in.
I think you mention extension method programming guide of extension method
You're after Extension Methods.
There is nothing wrong with them OOP speaking because you don't have access to private variables nor alter the behaviour of the object in any way.
Its only syntactic sugar on what you've described exactly.
Q: Is that a good programming practice to add some other functionality to well known classes?
This type of discussion really belongs on 'Programmers'.
Please take a look at this discussion on Programmers, that has a lot of philosophical points on using extension methods:
https://softwareengineering.stackexchange.com/questions/77427/why-arent-extension-methods-being-used-more-extensively-in-net-bcl
Also:
https://softwareengineering.stackexchange.com/questions/41740/when-to-use-abstract-classes-instead-of-interfaces-and-extension-methods-in-c?lq=1
Use Extensions methods
static class Program
{
static void Main(string[] args)
{
2.HelloWorld();
}
public static void HelloWorld(this int value)
{
Console.WriteLine(value);
}
}
You may use extension method
like this:
public static class IntExtensions
{
public static string HelloWorld(this int i)
{
return "Hello world";
}
}
As C# lacks support for freestanding functions, I find it hard to find a place to put conversion functions. For example, I'd like to convert an enum to a number. In C++, I would make the following freestanding function for this:
UINT32 ConvertToUint32(const MyEnum e);
How can I elegantly do this in C#? Should I make a dummy static class for holding the function, and if so, how can I find a meaningful name for it? Or should I make a partial class Convert?
Any ideas?
Thanks in advance.
Update: In retrospect, my example was not very well chosen, as there exists a default conversion between enum and int. This would be a better example:
Person ConvertToPerson(const SpecialPersonsEnum e);
The above example looks like a candidate for an Extension Method.
If that's not possible, I define them as static methods in a static class ; I'd normally put them in a static class called XXXHelper
I'd go with:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int ConvertToInt(this MyEnum e)
{
var m;
// ... Implementation
return m;
}
}
}
Then you'd simply use MyEnum.ConvertToInt(); The same can be done for multiple conversions all from within the same class. Extension methods are in a nutshell, damn sexy.
Also, Eric's comment about Type Converters got me googling. Pretty awesome, however I'm not sure how to use them with an Enum, but for other conversions, they're clean as a whistle to implement. Have a look here:
http://www.pluralsight.com/community/blogs/fritz/archive/2005/12/09/17343.aspx
I would recomend that you create and assembly that would contain all your helper methods/constants and enums that will be used in other projects.
This will allow you to easily include this assembly with other assemblies that need it and avoid circular references.
Can't you just use a cast for this? (UInt32)e. Or else call Convert.ToUInt32(e)
The idea of creating a static "dummy class" seems to be what Microsoft suggests:
http://msdn.microsoft.com/en-us/library/bb383974.aspx
I think in your particular example doing a partial class Convert makes the most sense.
I faced the similar problem once and I did this
class Program
{
static void Main(string[] args)
{
string s = "123";
int n = Convert.StringToInt(s);
}
}
class Convert
{
public static int StringToInt(string s)
{
// implementation
}
public static string IntToString(int n)
{
// implementation
}
}
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
{
}
}