ویژگی های کمتر استفاده شده در NET. - بخش هفتم
نویسنده: وحید محمدطاهری
تاریخ: ۱۳۹۶/۰۲/۱۹ ۲۳:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
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" );
}
}
class Program
{
public static void Main(string[] args)
{
DebugMode();
}
[Conditional("DEBUG")]
public static void DebugMode()
{
Console.WriteLine( "Debug mode" );
}
} #define ReleaseMode
[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 نمیتوانید دارا بودن آن مقدار را تست کنید و همیشه نتیجه صفر خواهد بود.
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 "، کامپایلرهای متن باز #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 );
}