I've noticed that .NET 4.5 has a new attribute called [CallerMemberNameAttribute] which, when attached to a parameter of a method, will supply the string name of the method that called that method (if that makes sense).
However, unfortunately (because I want to make something with XNA) I'm only targeting .NET 4.0.
I want to be able to do something like:
void MethodA() {
MethodB();
}
void MethodB() {
string callingMethodName = (...?);
Console.WriteLine(callingMethodName);
}
Where my output would be MethodA.
I know I could do this via stack trace, but that's a) Unreliable and b) Sloooow...
So I'm wondering if there's any other way to glean that information, however that may be...
I was hoping for any ideas or knowledge that anyone might have on the issue. Thanks in advance :)
If you use Visual Studio 2012 to compile this, you can write your own CallerMemberNameAttribute and use it the same way you would with .NET 4.5 even if you still target .NET 4.0 or 3.5. The compiler will still perform the substitution at compile time, even targeting an older framework version.
Just adding the following to your project will do the trick:
namespace System.Runtime.CompilerServices
{
public sealed class CallerMemberNameAttribute : Attribute { }
}
You could supply the caller name as a parameter to the called method. Not quite what you’re asking for, but it works without needing to access the stack frame:
[MethodImpl(MethodImplOptions.NoInlining)]
void MethodA()
{
string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
MethodB(methodName);
}
void MethodB(string callingMethodName)
{
Console.WriteLine(callingMethodName);
}
By using MethodBase.GetCurrentMethod(), you can ensure that your implementation remains refactor-safe – if the name of your method changes, the results would still be correct.
Don’t forget to mark your calling method with MethodImplOptions.NoInlining so as to avoid method inlining.
Related
I have a dll where I have one class which logs to a "channel", another Program listens to the "channel" and writes the logs to the screen.
The problem with the dll is that its grown over time and now there are many dependecies in it. I want to remove the logging part from this dll and place it in a debugging and logging dll.
The problem is that the debugging and logging dll has another namespace which I want to use in the class or rather I want to use the class in the namespace. My problem with this is that some developers used the namespace nearly exclusively when calling the methods instead of using it in the top of their classes.
It looks like the following for a static method:
Base.Manager.Logging.Send("Log something");
The other Dll has the simple namespace Trace
so it should look like this:
Trace.Logging.Send("Log something");
My question is, is there an elegant way to move the class and change the namespace without altering all the uses of the Methods ?
I could simply copy the class to the other dll and then use the old class as a wrapper which forwards all the calls to the other class in the Trace.dll but this approach seems a little bit hacky.
I hope this grafik illustrates what I mean because I think the simple text may be somewhat confusing
FYI: I don't have ReSharper
Unfortunately you can't. If you keep same namespace then you can use TypeForwardAttribute but if you also change namespace (not just assembly) then it doesn't work.
What I suggest is to move it to new class, keep old class to don't break code both at run-time & compile-time and forward all calls. Mark all old methods as obsolete (at least they'll be warned that code will change in future). Just to clarify:
namespace Base.Manager {
public static class Logger {
public static void Send(string message) {
// Do things
}
}
Step 1: empty your old deprecated class and forward calls to new class. Mark old methods as obsolete.
Will then be refactored to:
namespace Base.Manager {
[EditorBrowsable(EditorBrowsableState.Never)]
public static class Logger {
[Obsolete("This method is deprecated, please use Trace.Logger.Send")]
public static void Send(string message) {
// Delegate work to someone else...
Trace.Logger.Send(message);
}
}
It'll generate a warning (with given message) during compilation. Compile-time compatibility is saved. Note we also added EditorBrowsableAttribute, IntelliSense won't propose that Logger class when they start typing. This reduces (little bit) chances they will still use Base.Manager.Logger for new code.
Step 2: someday in future you'll change that warning to an error:
[Obsolete("This method is obsolete, use Trace.Logger.Send", true)]
This will break compilation but it'll preserve binaries compatibility. Other DLLs will still run (so you don't have to wait other developers complete this refactoring task) but they won't be able to compile unless they update.
Step 3: when all has been done and everyone moved to new class then simply remove Base.Manager.Logger class from your code.
Notes: that all process can be spanned across various releases: in 2.0 you deprecate old methods, in 2.1 you break compilation, in 3.0 you remove it from your code (this is especially useful if releases of your code and its users aren't in sync).
Just a word about name collisions: be aware that same class name (and methods) in two different namespace may lead to annoying name collisions. Imagine they have this code:
using Base.Manager;
void DoSomething() {
Logger.Send("I'm doing something.");
}
After your change (until Base.Manager.Logger isn't removed) they can't simply add another using:
using Base.Manager;
using Trace;
void DoSomething() {
Base.Manager.SomethingElse.DoIt();
// Compiler is confused: Base.Manager.Logger or Trace.Logger?
Logger.Send("I'm doing something.");
}
They need to full qualify which logger class they want to use:
Trace.Logger.Send("I'm doing something.");
Warning: be aware that if Trace isn't a new namespace then name collision may even break compilation immediately if they had both usings in their code (making ObsoleteAttribute useless).
If it's an issue or not for you/your users...I can't say.
I am building a v4.5 C#/.NET application and have to find which methods are dependent on a method. I want to list those methods out.
For example, if I have a method in a class and if this method uses another method:
public void Test()
{
CallMethodA();
CallMethodB();
}
When I pass in method Test to my application, I want it to print out CallMethodA and CallMethodB via reflection.
So far I have created this:
MethodBase methodBase = typeof(TestClass).GetMethod("Test");
var instructions = MethodBodyReader.GetInstructions(methodBase);
foreach (Instruction instruction in instructions)
{
MethodInfo methodInfo = instruction.Operand as MethodInfo;
if(methodInfo != null)
{
}
}
Mono.Cecil would be a good place to start. This question has lots of tutorials linked in answers.
However, this will only give you static analysis, i.e. the method calls at compile time. If you have method calls to an interface or virtual method then you won't know what other methods are actually being called at run-time. If you want to know what code was actually called at run-time you need to collect coverage information via instrumentation.
It is very much like creating your own application like .NET Reflector or dotPeek. If you want to know what calls are made within method of a class, you have to create something like Reflector. Also, do check out ILSpy; it can be of help.
About ILSpy
ILSpy is the open-source .NET assembly browser and decompiler.
Development started after Red Gate announced that the free version of
.NET Reflector would cease to exist by end of February 2011.
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.
Prettify gives types and methods the same class when tokenizing c# so they are colored the same. This is because methods are pascal case in c# instead of camel case like in java. This affects my blog and all stackoverflow c# code since they use prettify too.
Does anyone have a fix for this?
If not, you can at least star/vote the official bug that was reported in Mar/2009 so the authors take another look.
It is possible for identical syntax to have different meanings. There just isn't enough information to properly syntax highlight everything.
Take a look at this example:
static class Program
{
class Foo { public class Bar { public static void Func() { } } }
class Foo2 { public static Baz Bar2 { get; set; } }
class Baz { public void Func2() { } }
static void Main()
{
Foo.Bar.Func();
Foo2.Bar2.Func2();
}
}
In the first line, Bar is an inner class, and should be highlighted green. In the second line, Bar2 is a property of type Foo2, and should be highlighted black. Both Func and Func2 are functions, and should be highlighted black.
Here's how Visual Studio highlights that code.
I actually wrote my own syntax highlighting library to solve problems like this. It's pretty similar to prettify but you have to specify the language explicitly.
Website
Demo
The problem is that without context, it's impossible to find out whether it's a method or a type.
Take the following example:
var value = new Test();
Test();
This example instantiates a new Test and then calls the method Test. The only way to find out which is a class and which is a type is by having 1. the entire code base and 2. a compiler.
And then I haven't even touched invalid code.
That being said, I think that the current prettifier as used by SO does a terrific job of highlighting the code samples without any context whatsoever.
TextMate (OS X) or E-TextEditor (Windows)
TextMate/E-TextEditor will generate HTML & CSS from syntax highlighting for many, many languages.
Here is what you do:
Open the file in TextMate/E-TextEditor
Select the language from the menu at the bottom of the screen if it doesn't choose it automatically
Go to Bundles->TextMate->Create HTML From Document
This will create all the HTMl/CSS in a new document.
Note: Windows users also choose the 'TextMate' bundle (not 'E-TextEditor')
Profit!
Note: You will have to install the C# bundle for C# syntax (every other common language is included). To do this, install the "Get Bundles" bundle, and use that to install the C# bundle.
EDIT: Reading the comments I realized TextMate is only a solution for Mac users. Sometimes I forget about Windows.
You can also use E-TextEditor for Windows. The steps are the same.
I am writing a (very small) framework for checking pre- and postconditions of methods. Entry points are (they could be easily be methods; that doesn't matter):
public static class Ensures {
public static Validation That {
get { ... }
}
}
public static class Requires {
public static Validation That {
get { ... }
}
}
Obviously, checking the postconditions may be expensive, and isn't actually necessary, when the method isn't buggy. So I want a method which works like this:
public static class Ensures {
[ConditionalCallingCode("DEBUG")]
public static Validation ThatDuringDebug {
get { ... }
}
}
where ConditionalCallingCodeAttribute means that this method should only run when the calling code is compiled with the DEBUG symbol defined. Is this possible?
I want client code to look like this:
public class Foo {
public void Bar() {
... // do some work
Ensures.That // do these checks always
.IsNotNull(result)
.IsInRange(result, 0, 100);
Ensures.WhileDebuggingThat // only do these checks in debug mode
.IsPositive(ExpensiveCalculation(result));
return result;
}
}
Of course, I can simply not provide WhileDebuggingThat. Then the client code would look like this:
public class Foo {
public void Bar() {
... // do some work
Ensures.That // do these checks always
.IsNotNull(result)
.IsInRange(result, 0, 100);
#ifdef DEBUG
Ensures.That // only do these checks in debug mode
.IsPositive(ExpensiveCalculation(result));
#endif
return result;
}
}
This is the fallback plan if nothing else works out, but it breaks DRY really badly.
As I understand it, marking WhileDebuggingThat with [Conditional("DEBUG")] will emit (or not) this method depending on whether DEBUG is defined during the compilation of the library, not of the assemblies which reference this library. So I could do this and then write documentation telling the library users to link debug builds of their code with the debug build of the library, and release builds with release builds. This doesn't strike me as the best solution.
Finally, I could tell the library users to define this class inside their projects:
using ValidationLibrary;
public static class EnsuresWhileDebugging {
[Conditional("DEBUG")]
public static Validation That() {
return Ensures.That;
}
}
This should work as well, as far as I see, but still requires breaking the DRY principle, if only slightly.
Is this anything that the normal ConditionalAttribute doesn't do for you, aside from working on a property instead of a method? You may well need to change the way things are called so that you've got methods instead of properties - and the fact that it returns a value may cause issues.
It would help a lot if you'd show how your framework is used - currently we've not got a lot to work with.
Another thing to consider would be supplying a variety of binary builds of your library - so that the caller can just supply a different version which doesn't actually do any checking. Again though, it's hard to tell with only the code you've provided.
Any solution that is found here would be slower than the actual checks. Also, since it would not be build into the compiler like ConditionalAttribute, the parameters would still be calculated. If the postconditions could be very complicated, such as
Ensures.That.IsPositive(ExpensiveCalculation(result));
You might consider using icelava's suggestion to reflect on the calling assembly to find if it is built in debug or release - but then you must use some sort of delegate to delay the calculation - to ensure that it is only done when needed. e.g.:
Ensures.WhileDebugging.That. IsPositive(() => ExpensiveCalculation(result));
The IsPositive function should run the lambda and check its result, only after reflecting to find out if it should be calculated.
I have not tried this since I am gonna bathe and leave the house.
Call Assembly.GetCallingAssembly() to get the assembly where the method (class) calling your current executing method comes from.
Run a check on that Assembly object to see if it is Release or Debug build.
It sounds like most of what you're doing is already covered using Debug.Assert().
For that matter, this code would only ever run in debug mode (but you have to put up with catch-block slowness):
try
{
Debug.Assert(false);
}
catch (Exception e)
{
// will only and always run in debug mode
}
It appears that what I want is just not available. I will probably settle for providing an implicit conversion from Validation to bool, so that validation checking may be wrapped in Debug.Assert().
The Debug Assert method can be set/changed using a bool even after the program is compiled, if for example the value is taken from a project user seting:
Debug.Assert(!Properties.Settings.Default.UseAutoDebug);
I'm not sure but I think you could use ConditionalAttribute for this: whether to emit call or not to emit will depend on type of build of user, not your library. You can check this with Reflector or ILDasm: compile your samples and in Reflector (ILDasm) look whether call is emitted or not in sample project.
I have this occur:
Project A call 1 function of B.
B include this function:
Assembly.GetCallingAssembly().FullName
If build B at mode debug then running, this function return name of Project A, if build at mode release than return name of project B.
I dont know reason of this occur.
Please support me
Thanks