I know that if I mark code as DEBUG code it won't run in RELEASE mode, but does it still get compiled into an assembly? I just wanna make sure my assembly isn't bloated by extra methods.
[Conditional(DEBUG)]
private void DoSomeLocalDebugging()
{
//debugging
}
Yes, the method itself still is built however you compile.
This is entirely logical - because the point of Conditional is to depend on the preprocessor symbols defined when the caller is built, not when the callee is built.
Simple test - build this:
using System;
using System.Diagnostics;
class Test
{
[Conditional("FOO")]
static void CallMe()
{
Console.WriteLine("Called");
}
static void Main()
{
CallMe();
}
}
Run the code (without defining FOO) and you'll see there's no output, but if you look in Reflector you'll see the method is still there.
To put it another way: do you think the .NET released assemblies (the ones we compile against) are built with the DEBUG symbol defined? If they're not (and I strongly suspect they're not!) how would we be able to call Debug.Assert etc?
Admittedly when you're building private methods it would make sense not to include it - but as you can see, it still is built - which is reasonable for simplicity and consistency.
Related
So I ran a C# university program through de4dot and then reflector to decompile it and the following error appeared when I ran it in VS.
[assembly: System.Runtime.CompilerServices.Extension]
Error CS1112 Do not use
'System.Runtime.CompilerServices.ExtensionAttribute'. Use the 'this'
keyword
instead. Client C:\Users\user\Desktop\333\as2\decom\AssemblyInfo.cs 15 Active
I tried replacing the code with this and this() among other things but that just causes other problems. Can someone explain what I am to replace with 'this'? I feel like I am missing something obvious here.
The [assembly: Extension] attribute is added to an assembly by the compiler when the assembly contains extension methods. This happens automatically, and based on the error you're seeing, the compiler doesn't want you doing it explicitly. Assuming the rest of the decompiler output is correct, comment out the assembly-level attribute, and you should be fine.
That said, you should never assume that a decompiler's output is correct.
You're meant to add the this modifier to the method:
public static class FooExtensions
{
public static void DoSomething(this Foo foo)
{
...
}
}
That makes it an extension method.
In general thought, I wouldn't try to use a decompiler to "round trip" code - decompilers can be useful to see what the compiler has actually done, but there are various situations where the result won't be compilable.
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.
In classic C, I may have a library at version 1.0, which defines a constant in its .h file like:
#define LIBRARY_API_VERSION_1_0
And I can do things like this in my application code:
#include "LibraryApi.h"
// ...
int success;
#ifdef LIBRARY_API_VERSION_1_0
int param = 42;
success = UseThisMethodSignature(42);
#endif
#ifdef LIBRARY_API_VERSION_2_0
float param = 42.0f;
success = UseOtherMethodSignature(param);
#endif
Now I'm working in C#. So, apparently #defines are only scoped to the file they're defined in, so I looked into the solution described here of using a static class with constants. But, that solution requires the checking to happen at runtime, which introduces a number of problems:
Potentially inefficient, if I'm running over the same code over and over again checking an extra conditional (though if it's a const, perhaps the compiler or .NET runtime is smart enough to avoid this?)
You can't do things that would throw compiler errors. In my above example, I've defined param twice with two different types. Also UseOtherMethodSignature may not exist as a function, which will not compile if both blocks are there only separated by if/else.
So, what is the accepted solution for this type of problem? My scenario is that I have multiple versions of a web service API (with varying degrees of differences depending on what you're doing with it) and I want to be able to compile against either without commenting/uncommenting a bunch of code or some other equally silly manual process.
Edit
For what it's worth, I'd prefer a compile-time solution--in my scenario I know when I compile which version I'm going to use, I don't need to figure out which version of the library is available on the system at runtime. Yes, that will work, but seems like overkill.
I would aim to abstract this into different wrapper libraries. They would be separate projects in Visual Studio and reference different versions of your framework.
// Shazaam contract.
public interface IShazaamInvoker {
Boolean Shazaam();
}
// ShazaamWrapper.v1.dll implementation
public class ShazaamInvoker : IShazaamInvoker {
public void Shazaam() {
Int32 param = 42;
return UseThisMethodSignature(param);
}
}
// ShazaamWrapper.v2.dll implementation
public class ShazaamInvoker : IShazaamInvoker {
public void Shazaam() {
Single param = 42f;
return UseOtherMethodSignature(param);
}
}
// Determine, at runtime, which wrapper to use.
var invoker = (IShazaamInvoker)(/*HereBeMagicResolving*/)
invoker.Shazaam();
I suggest using a DI framework to load the appropriate class / dll. If you can refactor your code to use interfaces then you can create an abstraction layer across different versions. See this link as to the different frameworks available.
Perhaps another solution in keeping with the compile time nature of your question is to use generated code with T4
You must define a compilation symbol at the project level. You do that in the project properties. These symbols can be referenced with the #if directive.
You could also create a project build configuration that includes one or the other compilation symbol and also check the configuration in the project file to include one or the other .dll reference based on the symbol so that you can properly build and debug both versions just by choosing the version from the dropdown in the toolbar.
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.
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