DebuggerStepThroughAttribute
class Program { public static void Main(string[] args) { DebuggerStepThroughMethod1(); } [DebuggerStepThrough] public static void DebuggerStepThroughMethod1() { Console.WriteLine( "Method 1" ); DebuggerStepThroughMethod2(); } [DebuggerStepThrough] public static void DebuggerStepThroughMethod2() { Console.WriteLine( "Method 2" ); } }
ConditionalAttribute
class Program { public static void Main(string[] args) { DebugMode(); } [Conditional("DEBUG")] public static void DebugMode() { Console.WriteLine( "Debug mode" ); } }
#define ReleaseMode
Flags Enum Attribute
[System.Flags] public enum Permission { View = 1, Insert = 2, Update = 4, Delete = 8 }
public static void Main( string[] args ) { var permission = ( Permission.View | Permission.Insert ).ToString(); Console.WriteLine( permission ); // Displays ‘View, Insert’ var userPermission = Permission.View | Permission.Insert | Permission.Update | Permission.Delete; // To retrieve the value from property you can do this if ( ( userPermission & Permission.Delete ) == Permission.Delete ) { Console.WriteLine( "کاربر دارای مجوز دسترسی به عملیات حذف میباشد" ); } // In .NET 4 and later Console.WriteLine( userPermission.HasFlag( Permission.Delete ) ? "کاربر دارای مجوز دسترسی به عملیات حذف میباشد" : "کاربر مجوز دسترسی به عملیات حذف را ندارد"); }
نکته: در صورتیکه مقداری را برای enum تعریف کرده باشید، نمیتوانید آن را با مقدار 0 مشخص کنید (در زمانی که ویژگی flags را بر روی enum اضافه کرده باشید)، چرا که با استفاده از عملیات بیتی AND نمیتوانید دارا بودن آن مقدار را تست کنید و همیشه نتیجه صفر خواهد بود.
Dynamically Compile and Execute C# Code
CodeDOM
public static void Main( string[] args ) { var sourceCode = @"class DotNetTips { public void Print() { System.Console.WriteLine("".Net Tips""); } }"; var compiledAssembly = CompileSourceCodeDom( sourceCode ); ExecuteFromAssembly( compiledAssembly ); } static Assembly CompileSourceCodeDom( string sourceCode ) { CodeDomProvider csharpCodeProvider = new CSharpCodeProvider(); var cp = new CompilerParameters { GenerateExecutable = false }; cp.ReferencedAssemblies.Add( "System.dll" ); var cr = csharpCodeProvider.CompileAssemblyFromSource( cp, sourceCode ); return cr.CompiledAssembly; }
Roslyn
سکوی کامپایلر دات نت " Roslyn "، کامپایلرهای متن باز #C و VB.NET را به همراه APIهای تجزیه و تحلیل کد ارائه کرده است که با استفاده از این APIها میتوان ابزارهای آنالیز کد جهت استفاده در ویژوال استودیو را ایجاد کرد.
برای استفاده از Roslyn باید این کتابخانه را نصب کنید
Install-Package Microsoft.CodeAnalysis
حال مثال قبل را با استفاده از Roslyn بازنویسی میکنیم:
public static void Main(string[] args) { var sourceCode = @"class DotNetTips { public void Print() { System.Console.WriteLine("".Net Tips""); } }"; var compiledAssembly = CompileSourceRoslyn( sourceCode ); ExecuteFromAssembly( compiledAssembly ); } private static Assembly CompileSourceRoslyn(string sourceCode) { using ( var memoryStream = new MemoryStream() ) { var assemblyFileName = string.Concat( Guid.NewGuid().ToString(), ".dll" ); var compilation = CSharpCompilation.Create( assemblyFileName, new[] { CSharpSyntaxTree.ParseText( sourceCode ) }, new[] { MetadataReference.CreateFromFile( typeof( object ).Assembly.Location ) }, new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary ) ); compilation.Emit( memoryStream ); var assembly = Assembly.Load( memoryStream.GetBuffer() ); return assembly; } }
و جهت فراخوانی اسمبلی ساخته شده به هر دو روش بالا، از کد زیر استفاده میکنیم.
static void ExecuteFromAssembly( Assembly assembly ) { var helloKittyPrinterType = assembly.GetType( "DotNetTips" ); var printMethod = helloKittyPrinterType.GetMethod( "Print" ); var kitty = assembly.CreateInstance( "DotNetTips" ); printMethod.Invoke( kitty, BindingFlags.InvokeMethod, null, null, CultureInfo.CurrentCulture ); }