I was learning code contract but it doesn't throw me any error or anything. I am using Visual Studio 2019.
Here's the code:
using System.Diagnostics.Contracts;
namespace ConsoleApp1
{
class Calculations
{
public static void Division(string name)
{
Contract.Requires(!string.IsNullOrEmpty(name));
}
}
class Program
{
static void Main(string[] args)
{
string s = null;
Calculations.Division(s);
}
}
}
How is this not throwing me anything? I pretty much violated the contract when I call Division.
Most probably because of the following line in the documentation
Most methods in the contract class are conditionally compiled; that is, the compiler emits calls to these methods only when you define a special symbol, CONTRACTS_FULL, by using the #define directive. CONTRACTS_FULL lets you write contracts in your code without using #ifdef directives; you can produce different builds, some with contracts, and some without.
It is also mentioned in the documentation that once you setup and use the Code.Contracts UI, then the CONTRACTS_FULL is defined.
Related
I am making a class library Foo (Xamarin Android Library if relevant but I prefer a general .NET solution if possible), and I need something like this:
if (builtInDebugConfig)
{
this.DoSomething();
}
Now Foo.dll will certainly be compiled in Release mode when the above code is called. Therefore #if is not possible for sure, Conditional should not work also (correct me if I am wrong, I've read it's a compiler attribute too) (the answer of the question and my test confirms Conditional works). The closest I could think of is Debugger.IsAttached, however most of the time we test apps without a debugger attached.
Is there a way to detect if the calling assembly is compiled with DEBUG symbol/config? If possible I don't want the calling (app) code to have something like this in every app because it defeats the purpose:
#if DEBUG
Foo.IsDebug = true;
#endif
UPDATE: Clarification for why I want that: I want to enable Debug codes (i.e enable WebView debug signal) if the calling app is in in development and don't want such code to exist in final view. That's why I am interested in a solution that prevent such code leaking to Release build.
You can use Conditional in Foo to decorate a method - any calls to that method will depend on whether the calling code defines the relevant symbol. So something like:
[Conditional("DEBUG")]
public void MaybeSetDebugMode()
{
// Remember the decision
}
Then the calling code can unconditionally write code calling MaybeSetDebugMode, and the call will only actually be compiled in if DEBUG is defined when the calling code is compiled. The method in Foo itself will be compiled into Foo.dll regardless of the symbols defined when you compile it.
That's not the same as #if, which does depend on the symbols when you're compiling your code.
Note that this is how Debug.WriteLine etc work.
One downside of this: this code absolutely will exist in the "final build" unless you take more action. It has to, given that the existence of code in Foo.dll can't change depending on what calls it.
So you may actually want to use #if instead, for example:
#if FINAL_BUILD
public void MaybeSetDebugMode()
{
// This method exists so that the calling code will still build
// with the final DLL, but there won't be any "interesting" code
// for anyone to find.
}
#else
public void MaybeSetDebugMode()
{
// Interesting code goes here. This code won't be included in the final build,
// but callers can call it unconditionally, because there'll be an empty
// method in the final build.
}
#endif
Thanks to the comments and answers, I've found two working solutions, both are great but I think I will use Conditional in my final project. IsExecutingDebug checks if DebuggableAttribute is present in the Entry assembly, while Conditional is explained in Jon Skeet's answer.
namespace ClassLibrary1
{
public class Class1
{
public bool IsExecutingDebug()
{
#if DEBUG
Console.WriteLine("Debug in lib");
#endif
return Assembly.GetExecutingAssembly().IsInDebug();
}
[Conditional("DEBUG")]
public void ExecuteInDebugOnly()
{
Console.WriteLine("Hi!");
}
}
}
namespace System
{
public static class MyExtensions
{
public static bool IsInDebug(this Assembly assembly)
{
return assembly.GetCustomAttributes<DebuggableAttribute>().Any();
}
}
}
I want to mark a method as Obsolete, and also cause the compilation to fail if it is called from anywhere.
I came across a solution here How do I mark a method as Obsolete/Deprecated? .
an answer suggests this syntax, saying that the boolean modifier will achieve my wanted effect(failing compilation)
[Obsolete("Method1 is deprecated, please use Method2 instead.", true)]
However, while this worked on the same project; it didn't when calling the method from another project (i even had visual studio productivity power tools show an eror for it but compilation still succeeded)
is this by design? or is there a workaround?
If you use something marked as obsolete inside a method or class which is also marked as obsolete, the compiler will give you no warning or error.
Consider the following obsolete method in some class:
public class SomeClass
{
[Obsolete("Don't use",true)]
public static void ObsoleteMethod() { }
}
The expected behavior is that it yields a compiler error whenever it is used.
But if you use it in another obsolete method, you not even get a compiler warning.
public class AnotherClass
{
public void Method()
{
SomeClass.ObsoleteMethod(); // Compiler error
}
[Obsolete("Avoid use",false)]
public void AnotherObsoleteMethod()
{
SomeClass.ObsoleteMethod(); // No error and no warning
}
}
This is true also if the whole class is marked as obsolete:
[Obsolete()]
public class ObsoleteClass
{
public void Method()
{
SomeClass.ObsoleteMethod(); // No error
}
}
Which is better to use, and why, on a large project:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
or
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
It really depends on what you're going for:
#if DEBUG: The code in here won't even reach the IL on release.
[Conditional("DEBUG")]: This code will reach the IL, however calls to the method will be omitted unless DEBUG is set when the caller is compiled.
Personally I use both depending on the situation:
Conditional("DEBUG") Example: I use this so that I don't have to go back and edit my code later during release, but during debugging I want to be sure I didn't make any typos. This function checks that I type a property name correctly when trying to use it in my INotifyPropertyChanged stuff.
[Conditional("DEBUG")]
[DebuggerStepThrough]
protected void VerifyPropertyName(String propertyName)
{
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
Debug.Fail(String.Format("Invalid property name. Type: {0}, Name: {1}",
GetType(), propertyName));
}
You really don't want to create a function using #if DEBUG unless you are willing to wrap every call to that function with the same #if DEBUG:
#if DEBUG
public void DoSomething() { }
#endif
public void Foo()
{
#if DEBUG
DoSomething(); //This works, but looks FUGLY
#endif
}
versus:
[Conditional("DEBUG")]
public void DoSomething() { }
public void Foo()
{
DoSomething(); //Code compiles and is cleaner, DoSomething always
//exists, however this is only called during DEBUG.
}
#if DEBUG example: I use this when trying to setup different bindings for WCF communication.
#if DEBUG
public const String ENDPOINT = "Localhost";
#else
public const String ENDPOINT = "BasicHttpBinding";
#endif
In the first example, the code all exists, but is just ignored unless DEBUG is on. In the second example, the const ENDPOINT is set to "Localhost" or "BasicHttpBinding" depending on if DEBUG is set or not.
Update: I am updating this answer to clarify an important and tricky point. If you choose to use the ConditionalAttribute, keep in mind that calls are omitted during compilation, and not runtime. That is:
MyLibrary.dll
[Conditional("DEBUG")]
public void A()
{
Console.WriteLine("A");
B();
}
[Conditional("DEBUG")]
public void B()
{
Console.WriteLine("B");
}
When the library is compiled against release mode (i.e. no DEBUG symbol), it will forever have the call to B() from within A() omitted, even if a call to A() is included because DEBUG is defined in the calling assembly.
Well, it's worth noting that they don't mean the same thing at all.
If the DEBUG symbol isn't defined, then in the first case the SetPrivateValue itself won't be called... whereas in the second case it will exist, but any callers who are compiled without the DEBUG symbol will have those calls omitted.
If the code and all its callers are in the same assembly this difference is less important - but it means that in the first case you also need to have #if DEBUG around the calling code as well.
Personally I'd recommend the second approach - but you do need to keep the difference between them clear in your head.
I'm sure plenty will disagree with me, but having spent time as a build guy constantly hearing "But it works on my machine!", I take the standpoint that you should pretty much never use either. If you really need something for testing and debugging, figure out a way to make that testability seperate from the actual production code.
Abstract the scenarios with mocking in unit tests, make one off versions of things for one off scenarios you want to test, but don't put tests for debug into the code for binaries which you test and write for production release. These debug tests just hide possible bugs from devs so they aren't found until later in the process.
This one can be useful as well:
if (Debugger.IsAttached)
{
...
}
With the first example, SetPrivateValue won't exist in the build if DEBUG is not defined, with the second example, calls to SetPrivateValue won't exist in the build if DEBUG is not defined.
With the first example, you'll have to wrap any calls to SetPrivateValue with #if DEBUG as well.
With the second example, the calls to SetPrivateValue will be omitted, but be aware that SetPrivateValue itself will still be compiled. This is useful if you're building a library, so an application referencing your library can still use your function (if the condition is met).
If you want to omit the calls and save the space of the callee, you could use a combination of the two techniques:
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value){
#if DEBUG
// method body here
#endif
}
Let's presume your code also had an #else statement which defined a null stub function, addressing one of Jon Skeet's points. There's a second important distinction between the two.
Suppose the #if DEBUG or Conditional function exists in a DLL which is referenced by your main project executable. Using the #if, the evaluation of the conditional will be performed with regard to the library's compilation settings. Using the Conditional attribute, the evaluation of the conditional will be performed with regard to the compilation settings of the invoker.
I have a SOAP WebService extension to log network traffic using a custom [TraceExtension]. I use this only for Debug builds and omit from Release builds. Use the #if DEBUG to wrap the [TraceExtension] attribute thus removing it from Release builds.
#if DEBUG
[TraceExtension]
#endif
[System.Web.Service.Protocols.SoapDocumentMethodAttribute( ... )]
[ more attributes ...]
public DatabaseResponse[] GetDatabaseResponse( ...)
{
object[] results = this.Invoke("GetDatabaseResponse",new object[] {
... parmeters}};
}
#if DEBUG
[TraceExtension]
#endif
public System.IAsyncResult BeginGetDatabaseResponse(...)
#if DEBUG
[TraceExtension]
#endif
public DatabaseResponse[] EndGetDatabaseResponse(...)
Usually you would need it in Program.cs where you want to decide to run either Debug on Non-Debug code and that too mostly in Windows Services. So I created a readonly field IsDebugMode and set its value in static constructor as shown below.
static class Program
{
#region Private variable
static readonly bool IsDebugMode = false;
#endregion Private variable
#region Constrcutors
static Program()
{
#if DEBUG
IsDebugMode = true;
#endif
}
#endregion
#region Main
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
if (IsDebugMode)
{
MyService myService = new MyService(args);
myService.OnDebug();
}
else
{
ServiceBase[] services = new ServiceBase[] { new MyService (args) };
services.Run(args);
}
}
#endregion Main
}
It looks cool on MSDN:
Specifies that the method is declared, but its implementation is
provided elsewhere.
So I tried it in a console application:
public class Program
{
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
public static extern void Invoke();
static void Main(string[] args)
{
Invoke();
Console.Read();
}
}
Then what should I do now? Where can I provide the implementation of Program.Invoke?
The usage of ForwardRef goes pretty much like this:
consumer.cs
using System;
using System.Runtime.CompilerServices;
class Foo
{
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
static extern void Frob();
static void Main()
{
Frob();
}
}
provider.cs
using System;
using System.Runtime.CompilerServices;
class Foo
{
// Need to declare extern constructor because C# would inject one and break things.
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
public extern Foo();
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
static extern void Main();
static void Frob()
{
Console.WriteLine("Hello!");
}
}
Now the magic sauce. Open a Visual Studio command prompt and type:
csc /target:module provider.cs
csc /target:module consumer.cs
link provider.netmodule consumer.netmodule /entry:Foo.Main /subsystem:console /ltcg
This uses one of the lesser known functionality of the linker where we're linking managed modules together. The linker is able to gel together same-shaped types (they need to have the exact same methods, etc.). ForwardRef is the thing that actually lets you provide implementation elsewhere.
This example is kind of pointless, but you can imagine things getting more interesting if a single method is implemented in a different language (e.g. IL).
My understanding is that ForwardRef acts in the same way as extern, and is intended for guiding the runtime when the language you are using lacks direct support (via extern in C#). As such, the usage should be very similar to the extern modifier, most notably using [DllImport(...)].
Consider following piece of code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RemotingNonVirtualCall
{
class Program
{
static void Main(string[] args)
{
var domain = AppDomain.CreateDomain("Second Domain");
A extA = (A)domain.CreateInstanceAndUnwrap(typeof(A).Assembly.FullName, typeof(A).FullName);
Console.WriteLine(extA.CurrentDomain());
}
}
[Serializable]
sealed class A : MarshalByRefObject
{
public string CurrentDomain()
{
return AppDomain.CurrentDomain.FriendlyName;
}
}
}
Method A::CurrentDomain is non-virtual, class A is sealed. But CLR intercepts method call and redirect it to another instance. How it is possible? Is it some sort of voodoo magic? Does CLR make some exception in method calling for object inherited from MarshalByRefObject class? How is it performed?
Thanks for advance.
It's essentially magic, i.e. the ability to do this is built into the .NET runtime. The good news is that your code can also do this, if it needs to: http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx
The JIT compiler is keenly aware that it generates code for a proxy. You can have a look-see with the SSCLI20 source code, clr\src\vm\jithelpers.cpp, search for "proxy".