Yesterday i gone through some article about EventAggregator, there some shot of code written like this,
(Message.Text as object).PublishEvent(PublishEventNames.MessageTextChanged);
public static class ExtensionServices
{
//Supplying event broking mechanizm to each object in the application.
public static void PublishEvent<TEventsubject>(this TEventsubject eventArgs, string eventTopic)
{
ServicesFactory.EventService.GetEvent<GenericEvent<TEventsubject>>()
.Publish(new EventParameters<TEventsubject> { Topic = eventTopic, Value = eventArgs });
}
}
My question is, how the object got the method "PublishEvent". Is my OOP understanding is wrong?
It was implemented as an Extension Method on the object class.
For example, this extension method (from the linked article):
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
Is defined on the String class (by using the this String syntax and a static method on a static class) .
In the project that this is defined in String now has a WordCount method (so long as it is also in the correct namespace).
Extension methods are not actually part of the object that you appear to call the method on. Extension methods are in an additional lookup scope that the compiler looks in after looking for the method in the scope of the object itself.
So, for a method call like obj.MyExtension(), the compiler will look for "MyExtension" in the members of the type of the obj variable. It won't find any matches, because "MyExtension" isn't defined in the object's type. The compiler then looks for extension methods named "MyExtension" that are available in the current scope (because of using clauses) that have a this parameter whose type matches the type of the obj instance variable. If a match is found, then the compiler generates code to make a static method call that other method, passing obj in the this parameter.
I believe the extension methods scope is a "last chance" lookup - if the compiler can't find "MyExtension" in the available extensions, the next step is to fail with a compile error.
The tricky thing with extension methods is they're only accessible when you have added the appropriate using clause to the current source file and added a reference to the appropriate assembly that implements the extensions to bring them into scope.
Intellisense doesn't help you resolve these names by adding the appropriate using clause for you. As a user, you get used to calling a particular method on a particular type of object, and you mentally associate that method as being part of that type. When you're fleshing out a new source file it's very common to write calls to that method as you normally would and get "not found" compiler errors because you forgot to reference the namespace / assembly containing the extension method definition(s) to your source file.
The this part of this TEventsubject eventArgs determines that this is an Extension method.
It is only syntactic sugar to be able to write
TEventsubject eventArgs;
eventArgs.PublishEvent("topic");
Instead of
TEventsubject eventArgs;
ExtensionServices.PublishEvent(eventArgs, "topic");
PublishEvent is an extension method.
You can tell by the definition of the method, which includes the this keyword in the arguments list.
http://msdn.microsoft.com/en-us/library/bb383977.aspx
Extension methods are very useful syntactically; but they should be used judiciously:
1) They can clutter Intellisense if too many extensions are added for non-specific types (such as an object).
2) They should be used to augment class/interface inheritance, not replace it. IMO, If a method is shared across completely unrelated types, then it is a good candidate for an extension method. But if it is shared across related types, then it is a better candidate for a method in a base class.
Related
C# provides following signature characteristics to be used while function overloading.
We know that for overloading takes into consideration only arguments; their number and types, but the objective of polymorphism is to provide same name but different usage depending upon calling strategy.
If I have a class containing two methods with the same name and signature, while one is static and another is not, C# compiler throws an error; "Class already defines a member called 'foo' with the same parameter types".The call to both the methods are going to be different; one with the object name and the static one with a class name. Hence there is no ambiguity with calling strategy. Then why does it throw an error?
class Example {
public void foo() { }
public static void foo() { }
}
class Program
{
static void Main(string[] args)
{
Example e = new Example();
e.foo();
}
}
Reason why it is throwing an error is that static methods can be called from non-static methods without specifying type name. In this case, compiler won't be able to determine, which method is being called.
public class Foo()
{
public static void MyMethod() {};
public void MyMethod() {}
public void SomeOtherMethod()
{
MyMethod(); // which method we're calling static or non-static ?
}
}
EDIT
Just found this SO post regarding your case. You might want to check it also.
This error occurs because this is how the behavior is defined in the C# Language Specification. Any "ambiguous" usage (or ways to disambiguate such) is irrelevant, although such reasoning and edge-cases may have led the designers to not explicitly allow such a differentiation .. or it might simply be a C# codification of an underlying .NET CLI/CLR restriction1.
From "3.6 Signatures and overloading" in the C# specification (and in agreement with the linked documentation), formatted as bullets:
The signature of a method consists of
the name of the method,
the number of type parameters, and
the type and kind (value, reference, or output) of each of its formal parameters ..
Method modifiers, including static, are not considered as part of the method signature here.
And, from "1.6.6 Methods" we have the restriction and an agreeing summary:
The signature of a method must be unique in the class in which the method is declared. The signature of a method consists of the name of the method, the number of type parameters and {the number, modifiers, and types of} its parameters..
This restriction applies before (and independently of) the method being considered for polymorphism.
Also, as a closing note: instance methods must be virtual or accessed through an interface to be run-time polymorphic in C#. (Both method hiding and method overloading are arguably a form of compile-time polymorphism, but that's another topic..)
1There is support for this simply being the result of a restriction of the .NET CLI/CLR itself that is not worth bypassing (ie. for interoperability reasons). From "I.8.6.1.5 Method signatures" in ECMA-335:
A method signature is composed of
a calling convention [CLS Rule 15: "the only calling convention
supported by the CLS is the standard managed calling convention"],
the number of generic parameters, if the method is generic,
[omitted rule]
a list of zero or more parameter signatures—one for each parameter of the method—
and,
a type signature for the result value, if one is produced.
Method signatures are declared by method definitions. Only one constraint can be added to a
method signature in addition to those of parameter signatures [CLS Rule 15: "The vararg constraint is not part of the CLS"]:
The vararg constraint can be included to indicate that all arguments past this point are
optional. When it appears, the calling convention shall be one that supports variable
argument lists.
The intersection between the C#/CLS and ECMA signature components is thus the method name, "the number of generic parameters", and "a list of zero or more parameter signatures".
I feel your question is "why did the standard choose to forbid declaring two methods that differ only by the static keyword?", and therefore the answer "because the standard says so" does not look appropriate to me.
Now, the problem is, there could be any reason. The standard is the Law, and it can be arbitrary. Without the help of somebody who participated to the language's design, all we can do is speculate about the reasons, trying to uncover the spirit of the Laws.
Here is my guess. I see three main reasons for this choice:
Because other languages say so.
C++ and Java are inspirational languages for C#, and it makes sense to observe the same overloading rules as those languages. As to why it is this way in these languages, I don't know. I found a similar question on SO about C++, although no answer is given as to why it is this way (outside of "the standard says so").
Because it creates ambiguity that need to be resolved.
As others and OP noted, allowing the same signatures excepted for the static keyword forces the user to call the methods in an unambiguous way (by prefixing the class name or the instance name). This adds a level of complexity to the code. Of course this can already be done with fields and parameters. However some don't agree with this usage and prefer to choose different names (prefixing the fields with _ or m_) for the fields.
Because it does not make a lot of sense in OOP.
This is really my understanding here, so I could be completely wrong (at least #user2864740 thinks that the argument is dubious -- see comments), but I feel like static members are a way to introduce "functional programming" in OOP. They are not bound to a specific instance, so they don't modify the internal state of an object (if they modify the state of another object, then they should be a non-static method of this other object), in a way they are "pure".
Therefore I don't understand how a "pure function" could be semantically close enough of a regular object method so that they would share the same name.
The same question was asked to Eric Gunnerson, who worked on the C# language design team, and his answer was:
It is true that there would be no ambiguity between the two functions as far as a compiler is concerned. There would, however, be a considerable potential for confusion on the part of the user. It would be tough to find the right method in documentation, and once you did, hard to be sure that you are calling the right version (ie you could accidentally call the static version when you wanted the instance version).
Therefore, the reason it is not allowed is by design.
i) Problem hypothesis - obtain the following behavior :
Be able to call a static method off of a class: e.g. MyClass.MySpecialMethod()
Also be able to call a non-static method with the same return type, name and arguments off of an instance of the same class: e.g. instanceOfMyClass.MySpecialMethod()
ii) Context :
Reproduce the behavior inside an application that uses Dependency Injection.
Most of today's programming uses DI - it is almost an anti-pattern to call a non-static method off of a direct instance of a dependency (without that dependency having been previously injected with DI).
iii) Solution :
class Program
{
static void Main(string[] args)
{
// instead of class initialization we would have these registrations, e.g.:
// diContainer.Resolve<IMyApplication>().With<MyDIApplication>();
// diContainer.Resolve<ITerminator>().With<Terminator>();
IMyApplication app = new MyDIApplication(new Terminator());
app.Run();
}
public interface IMyApplication { void Run(); }
public class MyDIApplication : IMyApplication
{
private readonly ITerminator terminator;
public MyDIApplication(ITerminator terminatorDependency)
{
this.terminator = terminatorDependency;
}
public void Run()
{
terminator.Terminate(); // instance method call
Terminator.Terminate(); // static method call
}
}
public interface ITerminator { void Terminate(); }
public class Terminator : ITerminator
{
public static void Terminate() => Console.WriteLine("Static method call.");
void ITerminator.Terminate() => Console.WriteLine("Non-static method call.");
}
}
Conclusion:
Yes, the signatures of the two Terminate methods are not identical, because the non-static method is an explicit implementation of the interface which does not conflict with the static method,
But in truth, when using this solution in the context of dependency injection, what we really care about is the outcome, not the plumbing - which is that we managed to call a static method off a class, with practically the same return, name and args as a non-static method off an instance of that class injected with DI.
Check out this simple pseudo-code:
class A
{
public void B(){...}
public static void B(){...}
}
...
A A = new A();
A.B(); // <== which one is going to be called?
What is the difference between an extension method and a static method ?
I have two classes like this :
public static class AClass {
public static int AMethod(string ....)
{
}
}
and
public static class BClass {
public static int BMethod(this string ....)
{
}
}
I can use these like
AClass.AMethod('...');
or
'...'.BMethod();
Which is proposed ?
An extension method is still a static method. You can use it exactly as you'd use a normal static method.
The only difference is that an extension method allows you to use the method in a way that looks like it's part of the type, so you can write:
int result = stringValue.BMethod();
Instead of:
int result = BClass.BMethod(stringValue);
This works purely as a compile "trick" - the compiler sees the first form, and if the BClass is usable (it has a proper using and is in a referenced assembly), then it will turn it into the second method's IL for you. It's purely a convenience.
Which is proposed ?
This really depends. If you control the type, I'd recommend putting the methods on the type itself. This is typically more maintainable.
If you don't control the type, or you're trying to "extend" a common type (such as IEnumerable<T>), then extension methods may be a reasonable approach.
However, if the type is a very common type, I'd typically avoid extension methods, as they become "noise" in intellisense, which in turn can cause extra confusion. For example, I would personally not recommend adding extension methods on System.Object or System.String, etc.
You cannot override an extension method.
Only if the method has a different signature, then it can be overloaded.
Off course there are some limitations:
Extension Methods have to be implemented as static methods and in static classes (inside a non-nested, non-generic static class to be more precise).
You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.
Extension methods cannot access private variables in the type they are extending.
You can consider Extension Methods as a 'legal' way to add more static methods to existing classes without actually inheriting them.
But the funny thing is that unlike regular static methods of the class, you cannot call Extension Methods on a class level (you will get an compile time error if you try this), but instead you must invoke them on a instance of the class (as if they were some regular methods of the instance of that class, which they are not!!!).
Also, inside the Extension Method you can freely use public properties of the passed object instance on which the method is being invoked, you are by no means limited only to static object data. Only the Extension Method is static method, but the object on which is called is full, regular object instance.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does “this” mean in a static method declaration?
i go through a code snippet and found this keyword is used as function argument.
the code snippet is like
public static void AddCell(this Table table, object cell)
why AddCell has this keyword they can write likeAddCell(Table table, object cell)
please explain the situation when to use this keyword as function argument with small code sample as a result i can better understand. thanks.
Basically what is being defined in your example is an extension method. In a static method, if you define the first argument using the this keyword you are allowing the method to be called on instance objects of the type defined on the first argument.
In the example you stated you would be able to do something like this:
Table someTableInstance; /// must be instanciated somehow;
someTableInstance.AddCell(cell); // Call the AddCell method as if it was an instance method.
Hope it helps,
Regards,
Bruno
This syntax is used for extension methods.
These look a bit odd when you first see them written, but they are fabulous things - most of Linq is written as extension methods.
Here's a good intro tutorial - http://csharp.net-tutorials.com/csharp-3.0/extension-methods/ - which includes the example:
public static class MyExtensionMethods
{
public static bool IsNumeric(this string s)
{
float output;
return float.TryParse(s, out output);
}
}
which enables you to call:
"fred".IsNumeric()
this is the keyword for creating extension methods.
This way, while I have not changed the implementation of Table, I can call method AddCell on a member of Table.
MSDN:
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.
It's a declaring an extension method. The point is that as well as
MyStaticClass.AddCell(table, cell);
you can now just call
table.AddCell(cell);
assuming MyStaticClass is in the current namespace or namespaces you've usinged.
The 'this' keyword is used to create an extension method. For instance, if you are using a library class that you want to add a method to without inheriting a new derived type, you can create a static extension method. It is syntactical-sugar that places a regular static method onto an already known type.
For example:
public static int ToNumber( this string numberString )
{
int convertedInt = 0;
// logic goes here to convert to an int
return convertedInt;
}
Can be called like this:
string myNumberString = "5";
int num = myNumberString.ToNumber();
You didn't have to create an inherited class to do this but it reads cleanly.
Can someone explain to me why in the following the 3rd invocation of DoSomething is invalid?
( Error message is "The name 'DoSomething' does not exist in the current context" )
public class A { }
public class B : A
{
public void WhyNotDirect()
{
var a = new A();
a.DoSomething(); // OK
this.DoSomething(); // OK
DoSomething(); // ?? Why Not
}
}
public static class A_Ext
{
public static void DoSomething(this A a)
{
Console.WriteLine("OK");
}
}
Extension methods can be invoked like other static methods.
Change it to A_Ext.DoSomething(this).
If you're asking why it isn't implicitly invoked on this, the answer is that that's the way the spec was written. I would assume that the reason is that calling it without a qualifier would be too misleading.
Because DoSomething takes a parameter.
DoSomething(a) would be legal.
Edit
I read the question a bit wrong here.
Since your calling it a a normal static method, and not a extension method, you need to prefic with the class name.
So A_Ext.DoSomething(a); will work.
If you call it like a normal static method, all the same rules apply.
Your second variant works because B inhetits A, and therefore you still end up calling it as an extension method, but the third does not.
sorry about the first version above that does not work. I'll leave it to keep the comment relevant.
Extension methods are still static methods, not true instance calls. In order for this to work you would need specific context using instance method syntax (from Extension Methods (C# Programming Guide))
In your code you invoke the extension
method with instance method syntax.
However, the intermediate language
(IL) generated by the compiler
translates your code into a call on
the static method. Therefore, the
principle of encapsulation is not
really being violated. In fact,
extension methods cannot access
private variables in the type they are
extending.
So while normally, both syntaxes would work, the second is without explicit context, and it would seem that the IL generated can't obtain the context implicitly.
DoSomething requires an instance of A to do anything, and without a qualifier, the compiler can't see which DoSomething you need to invoke. It doesn't know to check in A_Ext for your method unless you qualify it with this.
I'm sure the answer is something obvious, and I'm kind of embarrassed that I don't really know the answer already, but consider the following code sample I picked up while reading "Professional ASP.NET MVC 1.0":
public static class ControllerHelpers
{
public static void AddRuleViolations(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors)
{
foreach (RuleViolation issue in errors)
modelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
}
I understand what this static method is doing, but what I don't understand is what purpose the word "this" is serving in the method signature. Can anyone enlighten me?
That is a new C# 3.0 feature called extension method.
It means, that you add a new method to your ModelStateDictionary objects. You can call it like a normal method:
yourModelStateDictionary.AddRuleViolations( errors );
See, that the first parameter (the 'this'-parameter) is skipped. It assigns just ModelStateDictionary as a valid target for your extension method.
The clue is, that you can do this with any class - even sealed or 3rd party classes, like .Net framework classes (for instance on object or string).
It means the method in question is an "extension method" and can be called as if it was a method of the class itself. See this article.
It is an extention method signature, It means the "AddRuleViolations" will be treated as an extention method of ModelStateDictionary.
From MSDN.
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.
Also see here: Extension Methods (C# Programming Guid)
It adds an extension method to all instances of ModelStateDictionary.