How do I extend a class with c# extension methods? [duplicate] - c#

This question already has answers here:
Can I add extension methods to an existing static class?
(18 answers)
Closed 1 year ago.
Can extension methods be applied to the class?
For example, extend DateTime to include a Tomorrow() method that could be invoked like:
DateTime.Tomorrow();
I know I can use
static DateTime Tomorrow(this Datetime value) { //... }
Or
public static MyClass {
public static Tomorrow() { //... }
}
for a similar result, but how can I extend DateTime so that I could invoke DateTime.Tomorrow?

Use an extension method.
Ex:
namespace ExtensionMethods
{
public static class MyExtensionMethods
{
public static DateTime Tomorrow(this DateTime date)
{
return date.AddDays(1);
}
}
}
Usage:
DateTime.Now.Tomorrow();
or
AnyObjectOfTypeDateTime.Tomorrow();

You cannot add methods to an existing type unless the existing type is marked as partial, you can only add methods that appear to be a member of the existing type through extension methods. Since this is the case you cannot add static methods to the type itself since extension methods use instances of that type.
There is nothing stopping you from creating your own static helper method like this:
static class DateTimeHelper
{
public static DateTime Tomorrow
{
get { return DateTime.Now.AddDays(1); }
}
}
Which you would use like this:
DateTime tomorrow = DateTimeHelper.Tomorrow;

Extension methods are syntactic sugar for making static methods whose first parameter is an instance of type T look as if they were an instance method on T.
As such the benefit is largely lost where you to make 'static extension methods' since they would serve to confuse the reader of the code even more than an extension method (since they appear to be fully qualified but are not actually defined in that class) for no syntactical gain (being able to chain calls in a fluent style within Linq for example).
Since you would have to bring the extensions into scope with a using anyway I would argue that it is simpler and safer to create:
public static class DateTimeUtils
{
public static DateTime Tomorrow { get { ... } }
}
And then use this in your code via:
WriteLine("{0}", DateTimeUtils.Tomorrow)

The closest I can get to the answer is by adding an extension method into a System.Type object. Not pretty, but still interesting.
public static class Foo
{
public static void Bar()
{
var now = DateTime.Now;
var tomorrow = typeof(DateTime).Tomorrow();
}
public static DateTime Tomorrow(this System.Type type)
{
if (type == typeof(DateTime)) {
return DateTime.Now.AddDays(1);
} else {
throw new InvalidOperationException();
}
}
}
Otherwise, IMO Andrew and ShuggyCoUk has a better implementation.

I would do the same as Kumu
namespace ExtensionMethods
{
public static class MyExtensionMethods
{
public static DateTime Tomorrow(this DateTime date)
{
return date.AddDays(1);
}
}
}
but call it like this new DateTime().Tomorrow();
Think it makes more seens than DateTime.Now.Tomorrow();

They provide the capability to extend existing types by adding new methods with no modifications necessary to the type. Calling methods from objects of the extended type within an application using instance method syntax is known as ‘‘extending’’ methods. Extension methods are not instance members on the type.
The key point to remember is that extension methods, defined as static methods, are in scope only when the namespace is explicitly imported into your application source code via the using directive. Even though extension methods are defined as static methods, they are still called using instance syntax.
Check the full example here
http://www.dotnetreaders.com/articles/Extension_methods_in_C-sharp.net,Methods_in_C_-sharp/201
Example:
class Extension
{
static void Main(string[] args)
{
string s = "sudhakar";
Console.WriteLine(s.GetWordCount());
Console.ReadLine();
}
}
public static class MyMathExtension
{
public static int GetWordCount(this System.String mystring)
{
return mystring.Length;
}
}

I was looking for something similar - a list of constraints on classes that provide Extension Methods. Seems tough to find a concise list so here goes:
You can't have any private or protected anything - fields, methods, etc.
It must be a static class, as in public static class....
Only methods can be in the class, and they must all be public static.
You can't have conventional static methods - ones that don't include a this argument aren't allowed.
All methods must begin:
public static ReturnType MethodName(this ClassName _this, ...)
So the first argument is always the this reference.
There is an implicit problem this creates - if you add methods that require a lock of any sort, you can't really provide it at the class level. Typically you'd provide a private instance-level lock, but it's not possible to add any private fields, leaving you with some very awkward options, like providing it as a public static on some outside class, etc. Gets dicey. Signs the C# language had kind of a bad turn in the design for these.
The workaround is to use your Extension Method class as just a Facade to a regular class, and all the static methods in your Extension class just call the real class, probably using a Singleton.

Unfortunately, you can't do that. I believe it would be useful, though. It is more natural to type:
DateTime.Tomorrow
than:
DateTimeUtil.Tomorrow
With a Util class, you have to check for the existence of a static method in two different classes, instead of one.

We have improved our answer with detail explanation.Now it's more easy to understand about extension method
Extension method: It is a mechanism through which we can extend the behavior of existing class without using the sub classing or modifying or recompiling the original class or struct.
We can extend our custom classes ,.net framework classes etc.
Extension method is actually a special kind of static method that is defined in the static class.
As DateTime class is already taken above and hence we have not taken this class for the explanation.
Below is the example
//This is a existing Calculator class which have only one method(Add)
public class Calculator
{
public double Add(double num1, double num2)
{
return num1 + num2;
}
}
// Below is the extension class which have one extension method.
public static class Extension
{
// It is extension method and it's first parameter is a calculator class.It's behavior is going to extend.
public static double Division(this Calculator cal, double num1,double num2){
return num1 / num2;
}
}
// We have tested the extension method below.
class Program
{
static void Main(string[] args)
{
Calculator cal = new Calculator();
double add=cal.Add(10, 10);
// It is a extension method in Calculator class.
double add=cal.Division(100, 10)
}
}

Related

Consume Extension method in non-static class

All of the examples for extension methods that I have seen consume the extension method in a class like:
class Program
{
static void Main()
{
...Call extension method here
}
}
These seem to work because the consuming class is static. Is there a way to consume an extension method in a non static class like below? I can't seem to find any examples like this.
I have my Extension Method class:
using System;
using System.Collections.Generic;
namespace AwesomeApp
{
public static class LinqExtensionMethods
{
public static IEnumerable<T> FindItemsBeforeAndAfter<T>(this IEnumerable<T> items, Predicate<T> matchFilling)
{
if (items == null)
throw new ArgumentNullException("items");
if (matchFilling == null)
throw new ArgumentNullException("matchFilling");
return items;
}
}
}
And I have my class that consumes the extention method
namespace AwesomeApp
{
public class Leaders : ILeaders
{
var leaders = GetAllLeaders();
var orderedleaders = leaders.OrderByDescending(o => o.PointsEarned);
var test = orderedleaders.FindItemsBeforeAndAfter(w => w.UserId == 1);
}
}
If I call the extension method from a static class I do not the the 'Extension method must be defined in a non-generic static class' error:
public class test
{
public void testfunc()
{
List<int> testlist = new List<int>() {1,2,3,4,5,6,7,8,9};
testlist.FindItemsBeforeAndAfter<int>(e => e == 5);
}
}
I have read through all the stackoverflow answers I can find on the non-generic static class error and they deal with writing your extension method but don't deal with consuming it.
So the question is: If using an extension method with a non-static class is not possible then is there any way to do something that works in a similar way? for example it can be called as .ExtensionMethod not Helper.ExtensionMethod(passedObject)??
Resolution: I thought I cut and pasted the extension method from public class Leaders : ILeaders to its own class so that I could make it static but I actually just copied it. The compiler error was pointing to the class name so I did not see the extension method still at the bottom of the file. The error message is accurate and everyone that answered is correct.
These seem to work because the consuming class is static.
No, that's incorrect. Extension methods definitely don't have to be consumed from static classes or static methods.
However, they do have to be declared in a class which is:
Non-nested
Non-generic
Static
You appear to be confusing calling with declaring - when you say:
If I call the extension method from a static class I do not the the 'Extension method must be defined in a non-generic static class' error
... you'll only get that if you try to declare the method in a class which doesn't satisfy all the above criteria. You should double click on the error to show where it's being generated - I'm sure you'll find it's the declaration, not the use of the method.
Note that your final example (class test) is not a static class, nor a static method.

Implement IEnumerable<SomeClass> extension method in SomeClass

I have a class like this:
public class SomeClass
{
public static IEnumerable<SomeClass> GetOutput(IEnumerable<SomeClass> items)
{
//Do stuff
}
}
This class is not static, but I want to make GetOutput an extension method for IEnumerable<SomeClass>. As such, I create a new static class:
public static class SomeClassExtensionMethods
{
public static IEnumerable<SomeClass> GetOutput(this IEnumerable<SomeClass> items)
{
return SomeClass.GetOutput(items);
}
}
Is there any more elegant way to do this? Why aren't we allowed to make SomeClass.GetOutput an extension method?
There is no more elegant way to do this unfortunately.
Why they aren't allowed was already answered here: Why are extension methods only allowed in non-nested, non-generic static class?
GetOutput() has to be an instance method, and cannot be static if you wish to extend it.
Why aren't we allowed to make SomeClass.GetOutput an extension method?
You can but not with the standard C# tools.
To the C# compiler, an extension method for a type is a static method that takes an instance of that type as its first parameter and is marked with System.Runtime.CompilerServices.ExtensionAttribute.
When defining an extension method in C#, the C# compiler won't allow the application of that attribute at all, suggesting that you use the this syntax, which does have the cited requirements. So, you could define the SomeClass in some other language or use a tool that adds the attribute after the C# compiler is done.
PostSharp (non-free edition) can do that. Just mark GetOutput with a different attribute and write code to replace it with System.Runtime.CompilerServices.ExtensionAttribute.
public class SomeClass
{
[ExtensionAspect]
public static IEnumerable<SomeClass> GetOutput(IEnumerable<SomeClass> items)
{
return items;
}
}
GetOutput is marked with ExtensionAspectAttribute, which is derived from a PostSharp aspect. Post-processing during the build runs the ProvideAspect method, which adds the desired attribute.
[AttributeUsage(AttributeTargets.Method)]
public class ExtensionAspectAttribute : MethodLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
var constructorInfo = typeof (System.Runtime.CompilerServices.ExtensionAttribute).GetConstructor(Type.EmptyTypes);
var objectConstruction = new ObjectConstruction(constructorInfo);
var aspectInstance = new CustomAttributeIntroductionAspect(objectConstruction);
yield return new AspectInstance(targetElement, aspectInstance);
}
}
So, in another project that references the binary assembly for SomeClass, this works:
var items = new [] { new SomeClass() };
var results = items.GetOutput();
That satisfies the C# compiler, however Intellisense doesn't see it as an extension method and ReSharper colors it as an error.
Of course, this is an academic exercise because there is little reason to not define the extension method in SomeClassExtensionMethods especially since it can be done in the same namespace and even the same .cs file as SomeClass.

Private class with Public method?

Here is a piece of code:
private class myClass
{
public static void Main()
{
}
}
'or'
private class myClass
{
public void method()
{
}
}
I know, first one will not work. And second one will.
But why first is not working? Is there any specific reason for it?
Actually looking for a solution in this perspective, thats why made it bold. Sorry
It would be meaningful in this scenario; you have a public class SomeClass, inside which you want to encapsulate some functionality that is only relevant to SomeClass. You could do this by declaring a private class (SomePrivateClass in my example) within SomeClass, as shown below.
public class SomeClass
{
private class SomePrivateClass
{
public void DoSomething()
{
}
}
// Only SomeClass has access to SomePrivateClass,
// and can access its public methods, properties etc
}
This holds true regardless of whether SomePrivateClass is static, or contains public static methods.
I would call this a nested class, and it is explored in another StackOverflow thread.
Richard Ev gave a use case of access inside a nested classes. Another use case for nested classes is private implementation of a public interface:
public class MySpecialCollection<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
return new MySpecialEnumerator(...);
}
private class MySpecialEnumerator : IEnumerator<T>
{
public bool MoveNext() { ... }
public T Current
{
get { return ...; }
}
// etc...
}
}
This allows one to provide a private (or protected or internal) implementation of a public interface or base class. The consumer need not know nor care about the concrete implementation. This can also be done without nested classes by having the MySpecialEnumerator class be internal, as you cannot have non-nested private classes.
The BCL uses non-public implementations extensively. For example, objects returned by LINQ operators are non-public classes that implement IEnumerable<T>.
This code is syntactically correct. But the big question is: is it useful, or at least usable in the context where you want to use it? Probably not, since the Main method must be in a public class.
Main() method is where application execution begin, so the reason you cannot compile your first class (with public static void Main()) is because you already have Main method somewhere else in your application. The compiler don't know where to begin execute your application.
Your application must have only one Main method to compile with default behavior otherwise you need to add /main option when you compile it.

Error: Extension method must be defined in a non-generic static class

I get the following compilation error at the class name.
Extension method must be defined in a non-generic static class
I am not using normal class. What could be the reason for this. I don't know and don't want to use extension methods.
As requested, here is my comment as an answer:
Without your code there isn't much we can do. My best guess is that you accidentally typed "this" somewhere in a parameter list.
Sample for extension method
public static class ExtensionMethods {
public static object ToAnOtherObject(this object obj) {
// Your operation here
}
}
I had the same problem, and solved it as follows. My code was something like this:
public static class ExtensionMethods
{
public static object ToAnOtherObject(this object obj)
{
// Your operation here
}
}
and I changed it to
public static class ExtensionMethods
{
public static object ToAnOtherObject(object obj)
{
// Your operation here
}
}
I removed the word "this" of the parameter of the method.
I'm guessing this relates to your previous list question; if so, the example I provided is an extension method, and would be:
public static class LinkedListUtils { // name doesn't matter, but must be
// static and non-generic
public static IEnumerable<T> Reverse<T>(this LinkedList<T> list) {...}
}
This utility class does not need to be the same as the consuming class, but extension methods is how it is possible to use as list.Reverse()
If you don't want it as an extension method, you can just make it a local static method - just take away the "this" from the firstparameter:
public static IEnumerable<T> Reverse<T>(LinkedList<T> list) {...}
and use as:
foreach(var val in Reverse(list)) {...}
The following points need to be considered when creating an extension method:
The class which defines an extension method must be non-generic and static
Every extension method must be a static method
The first parameter of the extension method should use the this keyword.
How about posting your code? Extension methods are declared by preceding the first parameter of a static method with this. Since you don't won't to use an extension method, I suspect you accidentally started a parameter list with this.
Look for something like:
void Method(this SomeType name)
{
}

.NET: Determine the type of “this” class in its static method

In a non-static method I could use this.GetType() and it would return the Type. How can I get the same Type in a static method? Of course, I can't just write typeof(ThisTypeName) because ThisTypeName is known only in runtime. Thanks!
If you're looking for a 1 liner that is equivalent to this.GetType() for static methods, try the following.
Type t = MethodBase.GetCurrentMethod().DeclaringType
Although this is likely much more expensive than just using typeof(TheTypeName).
There's something that the other answers haven't quite clarified, and which is relevant to your idea of the type only being available at execution time.
If you use a derived type to execute a static member, the real type name is omitted in the binary. So for example, compile this code:
UnicodeEncoding.GetEncoding(0);
Now use ildasm on it... you'll see that the call is emitted like this:
IL_0002: call class [mscorlib]System.Text.Encoding
[mscorlib]System.Text.Encoding::GetEncoding(int32)
The compiler has resolved the call to Encoding.GetEncoding - there's no trace of UnicodeEncoding left. That makes your idea of "the current type" nonsensical, I'm afraid.
Another solution is to use a selfreferecing type
//My base class
//I add a type to my base class use that in the
//static method to check the type of the caller.
public class Parent<TSelfReferenceType>
{
public static Type GetType()
{
return typeof(TSelfReferenceType);
}
}
Then in the class that inherits it, I make a self referencing type:
public class Child: Parent<Child>
{
}
Now the call type typeof(TSelfReferenceType) inside Parent will get and return the Type of the caller without the need of an instance.
Child.GetType();
You can't use this in a static method, so that's not possible directly. However, if you need the type of some object, just call GetType on it and make the this instance a parameter that you have to pass, e.g.:
public class Car {
public static void Drive(Car c) {
Console.WriteLine("Driving a {0}", c.GetType());
}
}
This seems like a poor design, though. Are you sure that you really need to get the type of the instance itself inside of its own static method? That seems a little bizarre. Why not just use an instance method?
public class Car {
public void Drive() { // Remove parameter; doesn't need to be static.
Console.WriteLine("Driving a {0}", this.GetType());
}
}
I don't understand why you cannot use typeof(ThisTypeName). If this is a non-generic type, then this should work:
class Foo {
static void Method1 () {
Type t = typeof (Foo); // Can just hard code this
}
}
If it's a generic type, then:
class Foo<T> {
static void Method1 () {
Type t = typeof (Foo<T>);
}
}
Am I missing something obvious here?
When your member is static, you will always know what type it is part of at runtime. In this case:
class A
{
public static int GetInt(){}
}
class B : A {}
You cannot call (edit: apparently, you can, see comment below, but you would still be calling into A):
B.GetInt();
because the member is static, it does not play part in inheritance scenarios. Ergo, you always know that the type is A.
For my purposes, I like #T-moty's idea. Even though I have used "self-referencing type" information for years, referencing the base class is harder to do later.
For example (using #Rob Leclerc example from above):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
Working with this pattern can be challenging, for example; how do you return the base class from a function call?
public Parent<???> GetParent() {}
Or when type casting?
var c = (Parent<???>) GetSomeParent();
So, I try to avoid it when I can, and use it when I must. If you must, I would suggest that you follow this pattern:
class BaseClass
{
// All non-derived class methods goes here...
// For example:
public int Id { get; private set; }
public string Name { get; private set; }
public void Run() {}
}
class BaseClass<TSelfReferenceType> : BaseClass
{
// All derived class methods goes here...
// For example:
public TSelfReferenceType Foo() {}
public void Bar(TSelfRefenceType obj) {}
}
Now you can (more) easily work with the BaseClass. However, there are times, like my current situation, where exposing the derived class, from within the base class, isn't needed and using #M-moty's suggestion just might be the right approach.
However, using #M-moty's code only works as long as the base class doesn't contain any instance constructors in the call stack. Unfortunately my base classes do use instance constructors.
Therefore, here's my extension method that take into account base class 'instance' constructors:
public static class TypeExtensions
{
public static Type GetDrivedType(this Type type, int maxSearchDepth = 10)
{
if (maxSearchDepth < 0)
throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0.");
const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor.
var stack = new StackTrace();
var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount);
var frame = skipFrames;
// Skip all the base class 'instance' ctor calls.
//
while (frame < maxCount)
{
var method = stack.GetFrame(frame).GetMethod();
var declaringType = method.DeclaringType;
if (type.IsAssignableFrom(declaringType))
return declaringType;
frame++;
}
return null;
}
}
EDIT
This methods will works only when you deploy PDB files with the executable/library, as markmnl pointed out to me.
Otherwise will be a huge issue to be detected: works well in developement, but maybe not in production.
Utility method, simply call the method when you need, from every place of your code:
public static Type GetType()
{
var stack = new System.Diagnostics.StackTrace();
if (stack.FrameCount < 2)
return null;
return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType;
}

Categories

Resources