Is it possible to determine what attributes are used inside a MethodBody?
For example:
void method1()
{
method2();
}
[Attr()]
void method2()
{
// NOP
}
Would there be any way for me to look at method1() and determine that it is using method2() or its associated attributes?
Your question is very confusing especially the first part...
Is it possible to determine what attributes are used inside a MethodBody?
... because even though method1() is calling method2(), and method2() is tagged with an attribute, in no sense is that attribute being used in method1().
Would there be any way for me to look at method1() and determine that it is using method2() or its associated attributes?
The short answer is - at runtime - no. You could of course manually tag method1() (and any other methods and any other methods) with something that denoted that they called method2() but I don't think this is what you're asking.
If you give us the context of what exactly you are trying to achieve it might help.
Finding out that method1 calls method2 from anywhere in your code is hard and not something that I believe has been done before. It is not clear to me why you would want to do that.
Using only Reflection in C# it is not possible to find out that method1 calls method2, as you can get only the raw binary representation of its Common Intermediate Language (CIL, the language used internally to represent all C#, VB, F# etc.. instructions).
byte[] methodIL = typeof(Program).GetMethod("method1")
.GetMethodBody()
.GetILAsByteArray();
However, Mono Cecil is a custom library designed to work with .Net assemblies and makes reading and working with the CIL of a method a lot easier. You could take a look at that and see if it suits your needs.
Related
Without using a library like PostSharp, is there a way to set up a custom attribute that I can have logic in that when attached to a method, will execute PRIOR to entering that method?
No; attributed are not intended to inject code. Tools like postsharp get around that with smoke and mirrors, but without that: no. Another option might be a decorator pattern,
perhaps dynamically implementing an interface (not trivial by any means). However, adding a utility method-call to the top of the method(s) is much simpler, and presumably fine since if you have access to add attributes you have access to add a method-call.
Or put another way: tools like postsharp exist precicely because this doesn't exist out-of-the-box.
// poor man's aspect oriented programming
public void Foo() {
SomeUtility.DoSomething();
// real code
}
In some cases, subclassing may be useful, especially if the subclass is done at runtime (meta-programming):
class YouWriteThisAtRuntimeWithTypeBuilder : YourType {
public override void Foo() {
SomeUtility.DoSomething();
base.Foo();
}
}
I'm refactoring the nasty out of a largeish codebase and need to find where a particular method, accepting instances of a fairly general interface, is called with a particular implementation of that interface.
For example, in the NastyStatic is the DoBadThings(IBusinessObject) method. I have about 50 classes that implement IBusinessObject in my business library, including DontHurtMe : IBusinessObject.
How can I find every call to NastyStatic.DoBadThings(foo), but only where foo is an instance of DontHurtMe?
EDIT: I'm after some sort of static analysis tool. Setting a dynamic watch in DoBadThings (or similar) and running the application isn't really an option. It will already throw an exception due to changes I've made to DontHurtMe, and there are far too many code paths to find all usages that way (at least until it goes live and my users start complaining).
Easy. Write an overload of DoBadThings that takes a DontHurtMe as a parameter. Now see where it's called. This won't detect the cases where the method is called with a declared IBusinessObject that happens to be a DontHurtMe - but I don't think static analysis can detect that. This gets all the calls of your method with a declared DontHurtMe.
ReSharper 5's Structural Search can do this. Supposing the following code:
class Program
{
static void Main(string[] args)
{
var hm = new HurtMe();
var dhm = new DontHurtMe();
DoBadThings(hm);
DoBadThings(dhm);
}
static void DoBadThings(IBusinessObject ibo) { }
}
interface IBusinessObject { }
class DontHurtMe : IBusinessObject { }
class HurtMe : IBusinessObject { }
Now, as noted, a R# Find Usages on DoBadThings, no matter what options we specify, will find both the invocations in Main.
But if we
Go to ReSharper | Find | Search with Pattern....
Add Placeholder | Expression, name it dhm and specify DontHurtMe as the type
In Search pattern, type DoBadThings($dbm$)
Click Find
we get in our results only the invocation of DoBadThings on the object with type statically identifiable as a DontHurtMe, and not the invocation on a HurtMe.
I do like the neatness of the procedure offered by #Carl Manaster, but this way gives an option for when you can't overload the method in question.
I can't come up with solution for static analysis. I just re-examined the options of ReSharper's "Find usages advanced..." and didn't find anything. You could put a condition breakpoint on this method with a condition like foo is DontHurtMe, but I suppose you know that already and it's better suited for the cases when you try to locate a bug than for refactoring purposes.
I know from this question that extension methods can only operate on class instances, not the static class itself. This means I can't extend useful static classes like Convert and Math.
What I want to know is, why is this the case? From the link above, there are some suggestions on how the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?
For example, here's a rationale behind why there is no built-in LINQ ForEach<T> extension for IEnumerable<T>.
the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?
There's no technical reason, and no philosophical reason. However, as I often point out, I don't have to provide a justification for not doing a feature. Features aren't cheap; they are extremely expensive and they must not only justify their own cost, they must justify the opportunity cost of not doing the hundred other features we could have done with that budget. We must justify the cost of features to our stakeholders, but we need not justify saving time and effort by not implementing features that don't meet our bar.
In particular, the proposed feature does nothing for LINQ; extension methods were added to make LINQ work. Anything that didn't make LINQ work was very hard to get into C# 3.0; we had a lot of work on the schedule and not much time to do it in. (I was surprised that automatic properties made it in.) Cutting an unnecessary feature before even designing it saved a lot of time and effort that was spent on other things that do make LINQ work.
In short: the suggested feature has never met our bar for net benefit over cost, and we've always had more important features to spend our limited time and effort on.
After reading through the answers, as well as some related questions, I've assembled my understanding of the issue here.
How extension methods work
First, it's important to realize that extensions are just syntactic sugar for static methods.
// Say you have an extension method that looks like this:
class Extensions
{
public static void Extend(this SomeClass foo) {}
}
// Here's how you call it
SomeClass myClass;
myClass.Extend();
// The compiler converts it to this:
Extensions.Extend(myClass);
The method doesn't actually become part of the class. This is why you can't access private members from an extension method. Extension methods change C# syntax only, and do not violate the concept of OOP accessibility. In fact, if you write an extension method and a normal static method that do the same thing, then decompile the MSIL, they are exactly the same.
Why extension methods exist
So if they don't add actual functionality, why have extension methods at all? The answer is LINQ:
// LINQ makes this easy to read
array.Where(i => i&1 == 0).Select(i => i*i);
// Without extension methods, we would have to do it like this
Enumerable.Select(Enumerable.Where(array, i => i&1 == 0), i => i*i);
In a way, all of LINQ is just syntactic sugar, since everything it can do could be written in a clunky, non LINQy way. Obviously the C# team felt that the readability gained by LINQ was worth it, but it begs the question, "why did they stop there?"
Why not other extension types?
Eric Lippert, one of the C# compiler devs, described in a blog post that a huge part of C# 3 was creating all of the constructs necessary for LINQ: "implicitly typed locals, anonymous types, lambda expressions, extension methods, object and collection initializers, query comprehensions, expression trees, [and] improved method type inference." Because the C# team was the most resource-limited team for the 2008 .NET release, additional types of extensions that weren't strictly necessary for LINQ were not included.
The team did consider implementing extension properties in C# 4, and actually wrote a working prototype, but it was dropped when they discovered it would not enable the WPF team as implemented (which was one of the motivators for the feature). Eric Lipper later said they they did consider extension methods for static classes, but could not justify the real-world benefits against the costs of implementation, testing, and maintenance.
A workaround
It is possible to write an extension method that gets close:
public static TResult DoSomething<TType, TResult>(this TType #class)
{
// access static methods with System.Reflection
return default(TResult);
}
// This works, but poorly
typeof(Math).DoSomething();
typeof(Convert).DoSomething();
But it's pretty ugly. It requires reflection, and can't support any kind of intelligent typing, since any Type can call it and that's likely not the intended functionality.
I believe the answer for your question is because it doesn't make any sense to extend with static methods. Main reason behind introducing Extension methods is not extending class which you do not own. Main reason is that it will allow reduce methods nesting in examples like these:
Enumerable.Select(Enumerable.Where(arr, i => i & 1 == 0), i => i*i); // not the best thing I ever read
arr.Where(i => i&1 == 0).Select(i => i*i); // wow, I see! These are squares for odd numbers
That is why there is no such point to have extension methods for static classes.
Extension methods operate on objects, not classes. If you want an extension method to operate on a class, I suppose you could do this:
public static T DoSomething<T>(this T #class)
where T:Type
{
// access static methods via reflection...
return #class;
}
Static extensions are possible in F# :
type Platform =
| Win32
| X64
override this.ToString() =
match FSharpValue.GetUnionFields(this, typeof<Platform>) with
| case, _ -> case.Name.Replace('X', 'x')
type Environment with
static member Platform =
if System.IntPtr.Size = 8 then Platform.X64 else Platform.Win32
Well its not only about not implemented, but it will cause confusion of where the method belongs to? Static extensions were introduced because linq came in later version and only to support linq in easy to code way, static extensions are useful.
Static extensions are useful only to make code more readable. It has no significance at runtime or compile time.
I have created an extension method for an ASP.NET MVC ViewPage, e.g:
public static class ViewExtensions
{
public static string Method<T>(this ViewPage<T> page) where T : class
{
return "something";
}
}
When calling this method from a View (deriving from ViewPage), I get the error "CS0103: The name 'Method' does not exist in the current context" unless I use the this keyword to call it:
<%: Method() %> <!-- gives error CS0103 -->
<%: this.Method() %> <!-- works -->
Why is the this keyword required? Or does it work without it, but I'm missing something?
(I think there must be a duplicate of this question, but I was not able find one)
Update:
As Ben Robinson says, the syntax to call extension methods is just compiler sugar. Then why can't the compiler automatically check the for extension methods of the current type's base types without requiring the this keyword?
A couple points:
First off, the proposed feature (implicit "this." on an extension method call) is unnecessary. Extension methods were necessary for LINQ query comprehensions to work the way we wanted; the receiver is always stated in the query so it is not necessary to support implicit this to make LINQ work.
Second, the feature works against the more general design of extension methods: namely, that extension methods allow you to extend a type that you cannot extend yourself, either because it is an interface and you don't know the implementation, or because you do know the implementation but do not have the source code.
If you are in the scenario where you are using an extension method for a type within that type then you do have access to the source code. Why are you using an extension method in the first place then? You can write an instance method yourself if you have access to the source code of the extended type, and then you don't have to use an extension method at all! Your implementation can then take advantage of having access to the private state of the object, which extension methods cannot.
Making it easier to use extension methods from within a type that you have access to is encouraging the use of extension methods over instance methods. Extension methods are great, but it is usually better to use an instance method if you have one.
Given those two points, the burden no longer falls on the language designer to explain why the feature does not exist. It now falls on you to explain why it should. Features have enormous costs associated with them. This feature is not necessary and works against the stated design goals of extension methods; why should we take on the cost of implementing it? Explain what compelling, important scenario is enabled by this feature and we'll consider implementing it in the future. I don't see any compelling, important scenario that justifies it, but perhaps there is one that I've missed.
Without it the compiler just sees it as a static method in a static class which takes page as it's first parameter. i.e.
// without 'this'
string s = ViewExtensions.Method(page);
vs.
// with 'this'
string s = page.Method();
On instance methods, 'this' is implicitly passed to each method transparently, so you can access all the members it provides.
Extension methods are static. By calling Method() rather than this.Method() or Method(this), you're not telling the compiler what to pass to the method.
You might say 'why doesn't it just realise what the calling object is and pass that as a parameter?'
The answer is that extension methods are static and can be called from a static context, where there is no 'this'.
I guess they could check for that during compilation, but to be honest, it's probably a lot of work for extremely little payoff. And to be honest, I see little benefit in taking away some of the explicitness of extension method calls. The fact that they can be mistaken for instance methods means that they can be quite unintuitive at times (NullReferenceExceptions not being thrown for example). I sometimes think that they should have introduced a new 'pipe-forward' style operator for extension methods.
It's important to note that there are differences between extension methods and regular methods. I think you've just come across one of them.
I'll give you an example of another difference: It's fairly easy to call an extension method on a null object reference. Fortunately, this is much more difficult to do with regular methods. (But it can be done. IIRC, Jon Skeet demonstrated how to do this by manipulating CIL code.)
static void ExtensionMethod(this object obj) { ... }
object nullObj = null;
nullObj.ExtensionMethod(); // will succeed without a NullReferenceException!
That being said, I agree that it seems a little unlogical that this is required to call the extension method. After all, an extension method should ideally "feel" and behave just like a normal one.
But in reality, extension methods are more like syntactic sugar added on top of the existing language than an early core feature that fits nicely into the language in all respects.
Because the extension method does not exist with the ViewPage class. You need to tell the compiler what you are calling the extension method on. Remember this.Method() is just compiler sugar for ViewExtensions.Method(this). It is the same way you can't just call an extention method within the middle of any class by the method name.
I am working on a fluent API and ran into the same issue. Even though I have access to the class I'm extending I still wanted the logic of each of the fluent methods to be in their own files. The "this" keyword was very unintuitive, users kept thinking the method was missing. What I did was make my class a partial class that implemented the methods I needed instead of using extension methods. I saw no mention of partials in the answers. If you have this question partials might be a better option.
We are currently discussing whether Extension methods in .NET are bad or not. Or under what circumstances Extension methods can introduce hard to find bugs or in any other way behave unexpectedly.
We came up with:
Writing an extension method for types that are not under your control (e.g. extending DirectoryInfo with GetTotalSize(), etc...) is bad, because the owner of the API could introduce a method that hides our extension - and might have different edge cases. For example testing for null in an extension method will automatically translate into a NullReferenceException if the extension method is no longer used due to hiding.
Question:
Are there any other dangerous situations than "hiding" that we are not thinking of?
Edit:
Another very dangerous situation.
Suppose you have an extension method:
namespace Example.ExtensionMethods
{
public static class Extension
{
public static int Conflict(this TestMe obj)
{
return -1;
}
}
}
And use it:
namespace Example.ExtensionMethods.Conflict.Test
{
[TestFixture]
public class ConflictExtensionTest
{
[Test]
public void ConflictTest()
{
TestMe me = new TestMe();
int result = me.Conflict();
Assert.That(result, Is.EqualTo(-1));
}
}
}
Notice that the namespace where you use it is longer.
Now you reference a dll with this:
namespace Example.ExtensionMethods.Conflict
{
public static class ConflictExtension
{
public static int Conflict(this TestMe obj)
{
return 1;
}
}
}
And your Test will fail! It will compile without a compiler error. It will simply fail. Without you even having to specify "using Example.ExtensionMethods.Conflict". The compiler will walk the namespace name and find Example.ExtensionMethods.Conflict.ConflictExtension before Example.ExtensionMethods.Extension and will use that without ever complaining about ambiguous extension methods. Oh the horror!
Some curiosities:
extension methods might be called on null instances; this might be confusing (but sometimes useful)
the "hiding" issue is a biggie if they have different intent
equally, you might get a different extension method with the same name from 2 different namespaces; if you only have one of the two namespaces, this could lead to inconsistent behaviour (depending on which)...
...but if somebody adds a similar (same signature) extension method in a second namespace that your code uses, it will break at compile time (ambiguous)
(edit) And of course, there is the "Nullable<T>/new()" bomb (see here)...
I disagree, the whole point of extension methods is to add your members to black boxed classes. Like everything else there are pitfalls, you must be mindful in naming, implementation and understand the pecking order of the methods.
One breakage we've just found in the MoreLINQ project: if you write a generic extension method, it's impossible to make sure it will work with all types. We've got a method with this signature:
public static IEnumerable<T> Concat<T>(this T head, IEnumerable<T> tail)
You can't use that with:
"foo".Concat(new [] { "tail" });
because of the string.Concat method...
I've used Ruby on Rails for almost as long as I've used C#. Ruby allows you to do something similar to the new extension methods. There are, of course, potential problems if someone named the method the same, but the advantages of being able to add methods to a closed class far outweigh the potential dissadvantage (which would probably be caused by bad design or poor planning).
One thing you can do to make sure extension methods don't conflict with other methods (extension or otherwise) is to use FxCop with rules such as Prevent Duplicate Extension Method Signatures.
First of all I believe your wording is a bit misleading. I take it you're talking about "types" and not "objects".
Secondly, the big advantage of extension methods is that you can add features to type you don't control. If you control the type, why not just modify the type instead of relying on extension methods?
We took the attitude in my team that Extension Methods are so useful that you can't realistically ban them, but so dangerous (principally because of the hiding issue) that you have to be a bit cautious. So we decided that all Extension Method names have to be prefixed with X (so we have a bunch of XInit...() methods to initialise controls in useful ways, for instance). That way a) the likelihood of a naming collision is reduced and b) the programmer knows he is using an Extension Method and not a class method.
What .Net calls extension methods are also a limited form a MonkeyPatching (try to ignore the php rant in there).
That should give you some material for your discussion.