What do you mean by "extension methods" in C#? - c#

Can anyone else explain this, (beginners approach). Thanks..

Extension Methods are just static methods in static classes that behaves like they were defined in other class.
In the first parameter before the type goes the keyword this wich indicates that is an extension method.
Example:
public static class Extensions
{
public static object ExtensionMethodForStrings( this string s, object otherParameter)
{
//....
return //whatever you want to return or not
}
}
This is an extension method on System.String that takes two parameters:
- string s : This is the instance variable
- object otherParameter: You can have as many as you want including none
You can call this method in two ways:
Static way:
string s = "Your string";
object o = new object(); // or whatever you want
object result = Extensions.ExtensionMethodForStrings(s,o);
Extension Method way
string s = "Your string";
object o = new object(); // or whatever you want
object result = s.ExtensionMethodForStrings(o);
In the second case it works as if the type string has an instance method called ExtensionMethodForStrings. Actually for the compiler the are equivalent.

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.
The C# article on Extension Methods.

An extension method is a static method in a static class whose first parameter is preceded by the keyword this.
The C# compiler has some syntactic sugar that can convert a call of x.Foo(bar) to SomeExtension.Foo(x, bar). This is used extensively by LINQ (Take, Skip, Where, Select, etc.) but you can also write your own extension methods if you wish.
This question includes lots of examples of useful extension methods:
What are your favorite extension methods for C#? (codeplex.com/extensionoverflow)

An extension method is a method that behaves (somewhat) like it is a member of a class, but it is not a member of that class. It can be called on members of that class, but has no reference to the internals of the class.
Extension methods are static methods, and must be members of a static class.
public static class StringExtensions
{
public static string HtmlEncode(this string dataString)
{
return HttpServerUtility.HtmlEncode(dataString);
}
}
The keyword "this" prior to the first parameter type identifies this as an extension method, and the class it extends.
It would be used this way:
string foo = "bar";
string myOutput = foo.HtmlEncode();

Related

How to add methods and fields to literal objects?

In object-oriented programming, everything is supposed to be an object. Starting from this postula, is it possible to add methods and fields to a literal object, such as a number, a string, a Boolean value or a character?
I noticed that in C#, we can use some methods and fields of the "Integer" class from a mathematical expression:
var a = (2 + 2).ToString();
I imagine that it is more syntactic sugar to access the "Integer" class and a method actually related to the mathematical expression (and / or its value).
But is it possible in C# to define one of the methods and fields to a literal object alone? Such as these examples:
"Hello, world!".print();
var foo = 9.increment();
This would probably be useless, but the language being object-oriented, this should be feasible. If this is not possible in C#, how could we do this with the object-oriented paradigm?
Sure, you can implement an extension method and have the desired syntax (however, Int32 class will not be changed):
public static class IntExtensions {
public static int increment(this int value) {
return value + 1;
}
}
...
// Syntax sugar: the actual call is "int foo = IntExtensions.increment(9);"
var foo = 9.increment();
In the current C# version (7.2) we can't add extension properties, extension events etc. These options can appear in C# 8.0 (Extension everything, https://msdn.microsoft.com/en-us/magazine/mt829270.aspx):
You don't add methods to a given instance of an object, you add methods to a type. Additionally, the language doesn't allow you to define what methods a string (or other type of) literal has, it defines what methods all strings have, of which string literals act just like any non-literal strings, and have exactly the same methods.
Note that (2 + 2) is not an instance of the "Integer" class, it will resolve to an instance of the System.Int32 struct. The difference isn't relevant to this behavior, but it's relevant to lots of others.
"Hello, world!".print();
This string is an instance of the String Class in C# which inherits from the Object class. So you have to create the print() method in the String Class in order to make this work.
You can use extension methods to achieve this, which must be static methods defined in a static class. In you example above, you could do the following:
public static class Extensions
{
public static int increment(this int num)
{
return ++num;
}
}

Understanding Generic method in C#

I moved from Java to C# and I am automating webservices in C#. There is a piece of code which is calling below method for converting the XML document to String
XmlDocument document = new XmlDocument();
document.Load(filePath + fileName);
var xml = document.ToXml();
public static string ToXml<T>(this T toSerialize) where T : class
Can someone explain me what exactly the above method is doing, i understand the return type is String but what is this piece of code meant ToXml<T>(this T toSerialize) where T : class
Can someone also explain me what is meant by "generic"?
It's an extension method:
public static string ToXml<T>(thisT toSerialize) where T : class
And a generic one at that, constrained to reference types:
public static string ToXml<T>(thisTtoSerialize)where T : class
This means that you can call the method on any reference type:
var foo = new YourClass
{
Bar = "Baz"
};
string xml = foo.ToXml<YourClass>();
And because the generic parameter type is used as a reference type, you can let it be inferred, omitting the generic argument:
string xml = foo.ToXml();
You could also just use File.ReadAllText() to load a text file into a string.
public static string ToXml<T>(this T toSerialize) where T : class
Let me break it down for you
<T> // This is the templated or generic type name.
where T : class // This syntax restricts the generic type to be a class (as opposed to a struct)
this T toSerialize) // The "this" keyword here can be ignored as it has nothing to do with the generics. It just tells that the caller can call this method like toSerialize.ToXml() instead of ContainingClass.ToXml(toSerialize)
In C#, you may or may not have to explicitly provide the generic type information at the call site, depending on the situation. In your case, it will be resolved without need for explicit specification
An explicitly specified call would like like
var xml = document.ToXml<XmlDocument>();
As you already have realized the var keyword is used instead of explicitly specifying string, since the compiler can infer the type very easily from the context.
You can read up on Generics and the contraints. Also, you can read up on Extension Methods. This should get you a solid understanding of the syntactical elements involved

Overload generic List's Add with extension method

I would like to overload a generic list's Add method so I can use collection initializations like:
var x = new List<Tuple<string>> { { "1", "2" }, { "1", "2" } };
(Where Tuple is a simple custom implementation of a binary tuple.)
However, I created an extension method, put a using directive in the cs file, and still get the "No overload for method 'Add' takes 2 arguments"-error.
Is it not possible to do (with an extension method)?
Extension method code:
namespace ExtensionMethods {
public static class Extensions{
public static void Add<T>(this List<Tuple<T>> self, T value1, T value2) {
self.Add(new Tuple<T> { value1, value2 });
}
}
}
It is not possible via extension methods. In order to make this syntax working you have to create your own collection class which will have void Add(T value1, T value2) signature.
P.S.: What you've done is not overload and there is no way to overload anything in existing class.
UPDATE: Looks like my first sentence should be: "It is not possible via extension methods in C#"
In C# 6.0[0] Microsoft allows the use of extensions methods in collection initializers. hurray :)
And since this isn't a .NET Framework or CLR change, but a compiler change, this feature can be used with .NET 4.0.
So the following is now valid C# code. (Tested in Visual Studio 2015 RC)
class Program
{
static void Main(string[] args)
{
var x = new List<Tuple<string,string>> { { "1", "2" }, { "1", "2" } };
}
}
public static class Extensions
{
public static void Add<T1,T2>(this List<Tuple<T1,T2>> self, T1 value1, T2 value2)
{
self.Add(Tuple.Create( value1, value2 ));
}
}
C# 6 Features [0]
You cannot implement constructors using extension methods.Extension method is nothing but a static method which takes in an instance of an object. Hence you need to have an instance first to be able to pass to it.
But you can just use AddRange() of the List to initialise your list.
Extension methods can't overload any method defined on their target type simply because they are not members of the target type. Extension methods do not ADD anything to their target types. They are just compiler magic that allow them to be called as if they were methods defined on their target type. In reality, they are defined in a separate static type, hence they can't overload any method on their target type.
Behind the scenes, the compiler replaces any calls to your extension method with a call to Extensions.
It looks like you are trying to make C# behave like Ruby and initialize an array of objects by passing a set of values, or at least imitate the behavior of dictionary initialization.
Unfortunately you can't do that without actually overloading List<>.
Collection initialization is just another bit of compiler magic that tries to find an Add method with as many arguments as there are items in the argument list. If it were otherwise you could define a conversion operator to convert a list to your Tuple type.
Why don't you just use the built-in object initializers? You'll just have to write a bit more code

How to extend methods to a class not to its instances

Extending methods to any instance is really easy:
public static string LeaveJustNumbers(this string text)
{
return Regex.Replace(text, #"[\D]", "");
}
...
string JustNumbers = "A5gfb343j4".LeaveJustNumber();
But what if i want to extend methods to a sealed class like string, to
work like:
string.Format("Hi:{0}","Fraga");
Is there any way to do it?
If you're talking about 'extending' static methods (or replacing existing ones), then as far as I know, no, you can't do it and I'm not sure why you'd want to.
The main point of extension methods is so that the calling style is that of an method call on the instance. It allows for more elegant syntax and method chaining, amongst other things. LINQ without extension methods would be horrendously painful, for example.
You have three options, one of which is extremely horrible:
Make a normal extension method that makes the call on the static method
public static string SomeExtensionMethod(this string name)
{
return string.Format("Hi:{0}", name);
}
Usage:
Console.WriteLine("Mr Smith".SomeExtensionMethod());
Create a static helper class and make the call using that
Console.WriteLine(MyHelperClass.SomeMethod("Mr Smith"));
And the evil one
Create a static helper class with the same name as the type you want to 'extend' (e.g. public class String) ... then duplicate the static target method's signature (Format) and watch everyone cry hot salty tears of confusion when they see a type named "string" that isn't from the "System" namespace and they have to smatter their .cs file with using String=MyCrazyHacks.String and/or explicit namespaces.
I'm not even sure if you could do this to "string" as it's an alias for System.String, so I've changed the example to use the name "String" instead.
namespace MyCrazyHacks
{
public static class String
{
public static System.String Format(
System.String str, params object[] zeParams)
{
// do bad, unspeakable things that confuses everyone
return System.String.Format(....);
}
}
}
Note: please don't do this because you will cause great suffering...

How to create extension methods for Types

I am writing an extension method for parsing JSON string for any given type. I wanted to use the method on types instead of instances like many examples we already know, but I somewhat feel it is not supported by Visual Studio. Can someone enlighten me here? The following is the method:
public static T ParseJson<T>(this T t, string str) where T: Type
{
if (string.IsNullOrEmpty(str)) return null;
var serializer = new JavaScriptSerializer();
var obj = serializer.Deserialize<T>(str);
return obj;
}
I want to call the method in this fashion:
var instance = MyClass.ParseJson(text);
Thanks
The short answer is it cannot be done; extension methods need to work on an instance of something.
To use the extension method, you would have to do:
var instance = typeof(MyClass).ParseJson(text);
The token "MyClass" is not a Type instamce intself, but using typeof will get you a Type to operate on. But how is this any better than:
var instance = JsonUtility.ParseJson<MyClass>(text);
Edit: Actually, the code for the extension method still would not do what you wanted. It will always return a "Type" object, not an instance of that Type.
You can't create extension methods that apply to the type itself. They can only be called on instances of a type.
As stated in the accepted answer, you can't. However, provided that you have an extension method that can be called from an instance of T:
public static T ParseJson<T>(this T t, string s)
You could write a utility method like this:
public static T ParseJson<T>(string s)
where T: new()
=> new(T).ParseJson(s);
And call it like this:
var t = Utilities.ParseJson<T>(s);
I am afraid that's the best you can do...
You can create and extension method
public static class MyExtensions
{
public static string Serialize<T>(this T self)
{
return JsonSerializer.Serialize(self);
}
}
And use it like
instance.Serialize();
You don't have to use it like instance.Serialize<Type>(); because most of the time (if not all the time) it can be inferred from the usage.

Categories