مرکز ایده های وحشتناک طراحی!
Nullable<T>.GetValueOrDefault Method
float? yourSingle = -1.0f; Console.WriteLine( yourSingle.GetValueOrDefault() ); yourSingle = null; Console.WriteLine( yourSingle.GetValueOrDefault() ); // assign different default value Console.WriteLine( yourSingle.GetValueOrDefault( -2.4f ) ); // returns the same result as the above statement Console.WriteLine( yourSingle ?? -2.4f );
در صورتیکه مقداری را به عنوان پیش فرض، به پارامتر این متد ارسال نکنید، مقدار پیش فرض آن از نوع استفاده شده بدست میآید.
شما میتوانید برای دیکشنری نیز یک متد Get امن ایجاد کنید (در صورت عدم وجود کلید، بجای پرتاب استثناء، مقدار پیش فرض بازگشت داده شود).
public static class DictionaryExtensions { public static TValue GetValueOrDefault< TKey, TValue >( this Dictionary< TKey, TValue > dic, TKey key ) { TValue result; return dic.TryGetValue( key, out result ) ? result : default(TValue); } }
و روش استفاده
var names = new Dictionary< int, string > { { 0, "Vahid" } }; Console.WriteLine( names.GetValueOrDefault( 1 ) );
ZipFile in .NET
var startPath = Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.Desktop ), "Start" ); var resultPath = Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.Desktop ), "Result" ); var extractPath = Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.Desktop ), "Extract" ); Directory.CreateDirectory( startPath ); Directory.CreateDirectory( resultPath ); Directory.CreateDirectory( extractPath ); var zipPath = Path.Combine( resultPath, Guid.NewGuid() + ".zip" ); ZipFile.CreateFromDirectory( startPath, zipPath ); ZipFile.ExtractToDirectory( zipPath, extractPath );
C# Preprocessor Directives
#if DEBUG #warning DEBUG is defined #endif
#if DEBUG #error DEBUG is defined #endif
در مثال زیر، در صورتیکه در خط اول break point قرار دهید و با کلید F10 برنامه را اجرا کنید، مشاهده میکنید که دیباگر، خطی را که بعد از دستور line hidden# نوشته شده است، در نظر نمیگیرد (برای دیباگ) اما اجرا میشود و دیباگر بر روی دستور بعد از line default# قرار میگیرد.
Console.WriteLine("Normal line #1."); // Set break point here. #line hidden Console.WriteLine("Hidden line."); #line default Console.WriteLine("Normal line #2.");
Stackalloc
static unsafe void Fibonacci() { const int arraySize = 20; int* fib = stackalloc int[arraySize]; var p = fib; *p++ = *p++ = 1; for ( var i = 2; i < arraySize; ++i, ++p ) { *p = p[-1] + p[-2]; } for ( var i = 0; i < arraySize; ++i ) { System.Console.WriteLine( fib[i] ); } }
Parallel.For & Parallel.ForEach
var nums = Enumerable.Range( 0, 1000000 ).ToArray(); long total = 0; // Use type parameter to make subtotal a long, not an int Parallel.For< long >( 0, nums.Length, () => 0, ( j, loop, subtotal ) => { subtotal += nums[j]; return subtotal; }, x => Interlocked.Add( ref total, x ) ); Console.WriteLine( "The total is {0:N0}", total );
var nums = Enumerable.Range( 0, 1000000 ).ToArray(); long total = 0; Parallel.ForEach< int, long >( nums, // source collection () => 0, // method to initialize the local variable ( j, loop, subtotal ) => // method invoked by the loop on each iteration { subtotal += j; //modify local variable return subtotal; // value to be passed to next iteration }, // Method to be executed when each partition has completed. // finalResult is the final value of subtotal for a particular partition. finalResult => Interlocked.Add( ref total, finalResult ) ); Console.WriteLine( "The total from Parallel.ForEach is {0:N0}", total );
IsInfinity
Console.WriteLine("IsInfinity(3.0 / 0) == {0}.", double.IsInfinity(3.0 / 0) ? "true" : "false");
dynamic Type
با استفاده از نوع dynamic می توان عملیات چک کردن نوع در زمان کامپایل را پشت سر گذاشت و در عوض این عملیات را به زمان اجرا، موکول داد.
نکته: نوع dynamic همانند نوع object در بسیاری از شرایط، یکسان رفتار میکند. اگرچه عملیاتهایی که شامل عبارتهایی از نوع dynamic هستند، یا نوع آن توسط کامپایلر بررسی میشوند و یا پذیرفته نمیشوند. کامپایلر اطلاعات مربوط به یک پردازش (روند) را یکجا بسته بندی میکند و این اطلاعات را بعداً در زمان اجرا ارزیابی میکند. به عنوان بخشی از این پردازش، متغیرهایی از نوع dynamic به متغیرهایی از نوع object کامپایل میشوند. بنابراین نوع dynamic فقط در زمان کامپایل وجود دارند (نه در زمان اجرا).
var i = 20; dynamic dynamicVariable = i; Console.WriteLine( dynamicVariable ); var stringVariable = "Example string."; dynamicVariable = stringVariable; Console.WriteLine( dynamicVariable ); var dateTimeVariable = DateTime.Today; dynamicVariable = dateTimeVariable; Console.WriteLine( dynamicVariable ); // The expression returns true unless dynamicVariable has the value null. if ( dynamicVariable is dynamic ) Console.WriteLine( "dynamicVariable variable is dynamic" ); // dynamic and the as operator. dynamicVariable = i as dynamic; // throw RuntimeBinderException if the associated object doesn't have the specified method. // The code is still compiling successfully. Console.WriteLine( dynamicVariable.ToNow1 );
همانطور که در مثال بالا مشاهده میکنید، شما میتوانید متغیرهایی از نوعهای مختلف را به یک شی از نوع dynamic اختصاص دهید. همچنین میتوانید برای بررسی یک متغیر که از نوع dynamic است یا خیر، از عملگر is استفاده کنید. اگر یک خصوصیت را که وجود ندارد، درخواست کنید (خط آخر مثال بالا)، خطای RuntimeBinderException پرتاب میشود.
ExpandoObject
dynamic sampleObject = new ExpandoObject(); sampleObject.FirstName = "Vahid"; sampleObject.LastName = "Mohammad Taheri"; sampleObject.Age = "28"; sampleObject.TestRemoveProperty = DateTime.Now; sampleObject.AsString = new Action( () => Console.WriteLine( "{0} {1} is {2} years old.", sampleObject.FirstName, sampleObject.LastName, sampleObject.Age ) ); sampleObject.AsString();
( (IDictionary< String, Object >)sampleObject ).Remove( "TestRemoveProperty" );
ObsoleteAttribute
ObsoleteAttribute بر روی تمامی عناصر یک برنامه بجز assemblies, modules، پارامترها و مقادیر بازگشتی قابل استفاده است. علامتگذاری یک عنصر به عنوان منسوخ شده، به کاربر استفاده کننده اطلاع میدهد که این عنصر در نسخههای آینده حذف خواهد شد.
با استفاده از پروپرتی Message آن پیامی را به کاربر استفاده کننده نشان خواهد داد و توصیه میشود در این پیام یک راه حل نیز ارائه شود.
پروپرتی IsError در صورتی که مقدار آن به true تعیین شده باشد و کامپایلر در صورتی که عنصری که این خصوصیت بر روی آن تعریف شده است، استفاده شده باشد، در پنجره Error List، پیام مربوط به Obsolete را نشان میدهد. برای مثال پس از استفاده از کلاس زیر، OrderDetailTotal به صورت warning و CalculateOrderDetailTotal به صورت Error در پنجره Error List نشان داده میشود.
public static class ObsoleteExample { // Mark OrderDetailTotal As Obsolete. [ObsoleteAttribute("This property (OrderDetailTotal) is obsolete. Use InvoiceTotal instead.", false)] public static decimal OrderDetailTotal { get { return 12m; } } public static decimal InvoiceTotal { get { return 25m; } } // Mark CalculateOrderDetailTotal As Obsolete. [ObsoleteAttribute("This method is obsolete. Call CalculateInvoiceTotal instead.", true)] public static decimal CalculateOrderDetailTotal() { return 0m; } public static decimal CalculateInvoiceTotal() { return 1m; } }
DefaultValueAttribute
DefaultValueAttribute جهت تعیین مقدار پیش فرض یک پروپرتی استفاده میشود. شما میتوانید یک DefaultValueAttribute را با هر مقداری ایجاد کنید. ایجاد مقدار پیش فرض برای یک پروپرتی باعث نمیشود که مقداردهی اولیهای به آن انجام گیرد؛ برای این کار نیاز به کدنویسی میباشد.
مثال زیر نحوه استفاده و مقداردهی اولیه پروپرتیها را نشان میدهد.
public class DefaultValueAttributeTest { public DefaultValueAttributeTest() { // Use the DefaultValue propety of each property to actually set it, via reflection. foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this)) { var attr = prop.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute; if (attr != null) prop.SetValue(this, attr.Value); } } [DefaultValue(28)] public int Age { get; set; } [DefaultValue("Vahid")] public string FirstName { get; set; } [DefaultValue("Mohammad Taheri")] public string LastName { get; set; } public override string ToString() { return $"{this.FirstName} {this.LastName} is {this.Age}."; } }
DebuggerBrowsableAttribute
در صورت استفاده از DebuggerBrowsableAttribute ، شما میتوانید نحوه نمایش یک عضو را در پنجره متغیرها، در زمان دیباگ، تعیین کنید.public class DebuggerBrowsableTest { [DebuggerBrowsable(DebuggerBrowsableState.Never)] // عدم نمایش در زمان دیباگ در پنجره متغیرها public string FirstName { get; set; } [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] // مقدار پیش فرض public string LastName { get; set; } [DebuggerBrowsable( DebuggerBrowsableState.RootHidden )] // عدم نمایش در زمان دیباگ در پنجره متغیرها public string FullName => FirstName + " " + LastName; [DebuggerBrowsable( DebuggerBrowsableState.RootHidden )] // تنها در زمانی که یک آرایه یا لیست باشد نمایش داده میشود public string[] FullNameArray => new string[] { FirstName + " " + LastName }; }
اگر از کد مثال بالا استفاده کنید و با استفاده از کلید F11 به صورت خط به خط دستورات را اجرا کنید، مشاهده خواهید کرد متغیر FirstName و FullName در پنجره Autos نشان داده نخواهد شد.
Operator ??
عملگر ?? در صورتی که عملوند سمت چپ آن تهی (null) نباشد، مقدار آن را باز میگرداند و در غیر اینصورت مقدار عملوند سمت راست خود را باز میگرداند. نوعهای تهی پذیر (nullable) میتوانند دارای مقدار و یا به صورت تعریف نشده باشند. عملگر ?? وقتی که یک نوع تهی پذیر به یک نوع غیرتهی پذیر انتساب داده میشود، مقدار پیش فرض آن را باز میگرداند.
int? x = null; int y = x ?? -1; Console.WriteLine("y now equals -1 because x was null => {0}", y); int i = DefaultValueOperatorTest.GetNullableInt() ?? default(int); Console.WriteLine("i equals now 0 because GetNullableInt() returned null => {0}", i); string s = DefaultValueOperatorTest.GetStringValue(); Console.WriteLine("Returns 'Unspecified' because s is null => {0}", s ?? "Unspecified");
NET 9 Release Candidate 2. منتشر شد
معماری لایه بندی نرم افزار #2
Today, we are releasing the .NET March 2021 Updates. These updates contains reliability and security improvements. See the individual release notes for details on updated packages.
You can download 5.0.4 , 3.1.13, 2.1.26 versions for Windows, macOS, and Linux, for x86, x64, Arm32, and Arm64.
Today, we are launching .NET Live TV, your one stop shop for all .NET and Visual Studio live streams across Twitch and YouTube. We are always looking for new ways to bring great content to the developer community and innovate in ways to interact with you in real-time. Live streaming gives us the opportunity to deliver more content where everyone can ask questions and interact with the product teams.
At Build 2019, Microsoft announced the release date for .NET Core 3.0 to be this coming September. This release includes the highly touted support for desktop platforms like WinForms and WPF. Today, there’s still a large developer base that’s building desktop applications using these .NET Windows desktop frameworks and by using .NET Core 3.0, you can now build desktop applications on the .NET Core platform.