C# 7 به همراه تغییرات قابل توجهی در مورد نحوهی دریافت خروجی از متدها است که نمونههایی از آنها را مانند tuples و out variable، پیشتر بررسی کردیم. در ادامه تغییرات جدید دیگری را به نام ref locals و ref returns نیز بررسی خواهیم کرد و هدف از آن، کاهش تعداد بار کپی کردن مقادیر و یا اعمال dereferencing جهت بالا بردن کارآیی برنامه هستند.
انتقال توسط مقدار
اگر پارامتری به صورت value type تعریف شود، این مقدار درون متد، ایجاد شده و حافظهای به آن اختصاص داده میشود و سپس در انتهای متد تخریب خواهد شد. بنابراین تغییری در مقدار آن، سبب انعکاس آن به فراخوان متد، نخواهد شد.
در این مثال متد PassByValue تنها یک کپی از مقدار متغیر a را دریافت میکند. بنابراین هر تغییری که درون متد PassByValue بر روی این مقدار دریافتی رخ دهد، به فراخوان آن منتقل نخواهد شد.
انتقال توسط ارجاع
برای بازگشت مقدار تغییر داده شدهی توسط یک متد، میتوان یک نوع خروجی را برای آن تعریف کرد. راه دیگر آن تعریف یک پارامتر توسط واژهی کلیدی ref است. پارامتری که به این روش تعریف شود، هم ارسال کنندهی مقدار و هم دریافت کنندهی تغییرات خواهد بود.
در این مثال متغیر x به مقدار متغیر a اشاره میکند. بنابراین هر تغییری که بر روی آن صورت گیرد، به متغیر a هم اعمال و منعکس خواهد شد.
متغیرهای out
با استفاده از واژهی کلیدی ref، میتوان یک مقدار را هم به تابع ارسال کرد و هم از آن دریافت نمود. اما اگر تنها قرار است مقداری از تابع بازگشت داده شود، میتوان از متغیرهای out استفاده کرد.
در حالت استفادهی از واژهی کلیدی out، نیازی به مقدار دهی اولیهی متغیر ارسالی به متد نیست و در اینجا روش جدید تعریف متغیرهای out را در C# 7 نیز مشاهده میکنید که نیازی نیست تا ابتدا int a را تعریف کرد و سپس در متد Out آنرا فراخوانی نمود. میتوان کل عملیات را به صورت خلاصه در یک سطر ذکر کرد.
البته اگر تنها قرار است یک مقدار را از یک متد دریافت کنیم، بهتر است نوع خروجی متد را مشخص کرد و از آن استفاده نمود؛ بجای استفادهی از متغیرهای out. یک نمونه کاربرد مفید متغیرهای out در خود فریم ورک و توسط متد TryParse وجود دارد:
Ref Locals در C# 7
در C# 7، امکان تعریف متغیرهای محلی از نوع ref نیز وجود دارد:
در اینجا متغیر x1 دارای ارجاعی است به متغیر x. بنابراین تغییر مقدار x1، به متغیر x نیز منعکس خواهد شد.
باید دقت داشت که نمیتوان یک مقدار را به یک ref variable نسبت داد:
به این ترتیب امکان اشتباه گرفتن بین value variables و reference variables توسط کامپایلر گوشزد خواهد شد:
Ref Returns در C# 7
در C# 7، واژهی کلیدی ref را به همراه نوع خروجی نیز میتوان بکار برد:
در این مثال ارجاعی به اولین عضو آرایهی تعریف شده، به عنوان خروجی متد بازگشت داده میشود. همچنین میتوان این کد را به صورت سادهتر ذیل نیز نوشت:
باید دقت داشت که یک متغیر int محلی را نمیتوان به صورت ref بازگشت داد. علت اینجا است که متغیر int یک value type است و در انتهای متد تخریب خواهد شد. بنابراین امکان بازگشت آن به صورت ref میسر نیست. اما آرایهها reference type بوده و بر روی heap تشکیل میشوند. در این حالت متغیر int داخل آرایه را میتوان به صورت ref بازگشت داد.
هرچند امکان بازگشت یک متغیر محلی int به صورت ref وجود ندارد، اما اگر این متغیر به صورت ref به تابع ارسال شده باشد، این امکان میسر است:
چند نکته: امکان تعریف فیلد ref و یا خاصیت get;set دار از نوع ref وجود ندارد. اما تعریف خواصی که یک ref را بازگشت میدهند، میسر هستند:
مزیت کار با ref returns
ref returnها شاید آنچنان در کدهای روزمرهی #C بکارگرفته نشوند، اما نیاز به کدهای unsafe و کار مستقیم با pointers را به حداقل میرسانند و به آن میتوان لقب safe pointer را اطلاق کرد؛ از این جهت که این کد هنوز هم یک managed code است و نه یک unsafe code.
مهمترین مزیت این قابلیت جدید را در قطعه کد فوق ملاحظه میکنید. در طراحی بازیها عموما استفادهی از آرایههای بزرگ از پیش تخصیص داده شدهی structها بسیار مرسوم است (چون میزان مصرف حافظهی کمتری را نسبت به نوعهای ارجاعی دارند و فشار کمتری را به GC وارد میکنند). اکنون با معرفی این قابلیت، دیگر نیازی نیست تا مدام آرایههای بزرگی از structها را از قسمتی به قسمت دیگر کپی کرد و سپس بر روی عناصری از آنها عملیاتی را انجام داد و مجددا این حاصل را به مکان مدنظر کپی کرد. در اینجا بدون کپی کردن value types میتوان با ایجاد ارجاعی به آنها، تغییرات مدنظر را به آنها اعمال کرد.
انتقال توسط مقدار
اگر پارامتری به صورت value type تعریف شود، این مقدار درون متد، ایجاد شده و حافظهای به آن اختصاص داده میشود و سپس در انتهای متد تخریب خواهد شد. بنابراین تغییری در مقدار آن، سبب انعکاس آن به فراخوان متد، نخواهد شد.
static void PassByValueSample() { int a = 1; PassByValue(a); Console.WriteLine($"after the invocation of {nameof(PassByValue)}, {nameof(a)} = {a}"); } static void PassByValue(int x) { x = 2; }
انتقال توسط ارجاع
برای بازگشت مقدار تغییر داده شدهی توسط یک متد، میتوان یک نوع خروجی را برای آن تعریف کرد. راه دیگر آن تعریف یک پارامتر توسط واژهی کلیدی ref است. پارامتری که به این روش تعریف شود، هم ارسال کنندهی مقدار و هم دریافت کنندهی تغییرات خواهد بود.
static void PassByReferenceSample() { int a = 1; PassByReference(ref a); Console.WriteLine($"after the invocation of {nameof(PassByReference)}, {nameof(a)} = {a}"); } static void PassByReference(ref int x) { x = 2; }
متغیرهای out
با استفاده از واژهی کلیدی ref، میتوان یک مقدار را هم به تابع ارسال کرد و هم از آن دریافت نمود. اما اگر تنها قرار است مقداری از تابع بازگشت داده شود، میتوان از متغیرهای out استفاده کرد.
static void OutSample() { Out(out int a); Console.WriteLine($"after the invocation of {nameof(Out)}, {nameof(a)} = {a}"); } static void Out(out int x) { x = 2; }
البته اگر تنها قرار است یک مقدار را از یک متد دریافت کنیم، بهتر است نوع خروجی متد را مشخص کرد و از آن استفاده نمود؛ بجای استفادهی از متغیرهای out. یک نمونه کاربرد مفید متغیرهای out در خود فریم ورک و توسط متد TryParse وجود دارد:
if (int.TryParse("42", out var result)) { Console.WriteLine($"the result is {result}"); }
Ref Locals در C# 7
در C# 7، امکان تعریف متغیرهای محلی از نوع ref نیز وجود دارد:
int x = 3; ref int x1 = ref x; x1 = 2; Console.WriteLine($"local variable {nameof(x)} after the change: {x}");
باید دقت داشت که نمیتوان یک مقدار را به یک ref variable نسبت داد:
ref int i = sequence.Count();
ref int number1 = null; // ERROR ref int number2 = 42; // ERROR
Ref Returns در C# 7
در C# 7، واژهی کلیدی ref را به همراه نوع خروجی نیز میتوان بکار برد:
static ref int ReturnByReference() { int[] arr = { 1 }; ref int x = ref arr[0]; return ref x; }
static ref int ReturnByReference2() { int[] arr = { 1 }; return ref arr[0]; }
هرچند امکان بازگشت یک متغیر محلی int به صورت ref وجود ندارد، اما اگر این متغیر به صورت ref به تابع ارسال شده باشد، این امکان میسر است:
static ref int ReturnByReference3(ref int x) { x = 2; return ref x; }
چند نکته: امکان تعریف فیلد ref و یا خاصیت get;set دار از نوع ref وجود ندارد. اما تعریف خواصی که یک ref را بازگشت میدهند، میسر هستند:
class Thing1 { ref string _Text1; /* Error */ ref string Text2 { get; set; } /* Error */ string _text = "Text"; ref string Text3 { get { return ref _text; } } // Properties that return a reference are allowed }
مزیت کار با ref returns
ref returnها شاید آنچنان در کدهای روزمرهی #C بکارگرفته نشوند، اما نیاز به کدهای unsafe و کار مستقیم با pointers را به حداقل میرسانند و به آن میتوان لقب safe pointer را اطلاق کرد؛ از این جهت که این کد هنوز هم یک managed code است و نه یک unsafe code.
private MyBigStruct[] array = new MyBigStruct[10]; private int current; public ref MyBigStruct GetCurrentItem() { return ref array[current]; }
اشتراکها
F# 4.7 منتشر شد
در این مطلب نکات کار با تصاویر را توسط افزونهی Web Esstentials بررسی میکنیم. این افزونه قابلیتهای زیر را در کار با تصاویر در اختیار شما قرار میدهد:
بهینهسازی تصاویر
یکی از موارد مهمی که باید مورد توجه قرار بگیرد، استفاده از تصاویر کم حجم در وبسایت میباشد. روشهای مختلفی جهت بهینهسازی تصاویر مورد استفاده در سایت وجود دارند، به طور مثال جهت بهینهسازی تصاویر PNG میتوانید از ابزار PNGGauntlet استفاده کنید. همچنین اینجا نیز یک ابزار آنلاین موجود میباشد. افزونهی Web Essentails این قابلیت را به آسانی در اختیار شما قرار میدهد؛ اینکار را میتوانید توسط این افزونه به روشهای زیر انجام دهید:
- کلیک راست بر روی تصویر
برای اینکار بر روی فایلی که میخواهید optimize کنید، کلیک راست کرده و از منوی ظاهر شده گزینه Web Essentials و سپس Optimize Image را انتخاب کنید:
در قسمت status bar نیز میتوانید نتیجه را مشاهده کنید:
- انتخاب چندین تصویر
روال قبلی را میتوانید برای چندین فایل انتخاب شده و یا یک پوشه تکرار کنید:
- بهینهسازی تصاویر موجود در فایلهای CSS
همچنین امکان بهینهسازی تصاویر داخل فایلهای CSS نیز توسط این افزونه امکان پذیر است:
همانطور که در تصویر فوق مشاهده میکنید میتوانیم تصاویری که به صورت Data Uri درون کد پیوست شده اند را با کلیک بر روی Save to file به صورت یک فایل ذخیره کنیم.
ایجاد تصاویر Sprite
یکی دیگر ار قابلیتهای افزونه Web Essentials امکان تهیه تصاویر به صورت Sprite می باشد. برای اینکار کافی است به این صورت عمل کنید:
بعد از کلیک بر روی Create image sprite باید یک نام برای آن تعیین کنید و سپس بر روی کلید Save کلیک کنید. با اینکار یک فایل از نوع XML با پسوند sprite برای شما ساخته خواهد شد:
<?xml version="1.0" encoding="utf-8"?> <sprite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://vswebessentials.com/schemas/v1/sprite.xsd"> <settings> <!--Determines if the sprite image should be automatically optimized after creation/update.--> <optimize>true</optimize> <!--Determines the orientation of images to form this sprite. The value must be vertical or horizontal.--> <orientation>vertical</orientation> <!--File extension of sprite image.--> <outputType>png</outputType> <!--Determin whether to generate/re-generate this sprite on building the solution.--> <runOnBuild>false</runOnBuild> <!--Use full path to generate unique class or mixin name in CSS, LESS and SASS files. Consider disabling this if you want class names to be filename only.--> <fullPathForIdentifierName>true</fullPathForIdentifierName> <!--Use absolute path in the generated CSS-like files. By default, the URLs are relative to sprite image file (and the location of CSS, LESS and SCSS).--> <useAbsoluteUrl>false</useAbsoluteUrl> <!--Specifies a custom subfolder to save CSS files to. By default, compiled output will be placed in the same folder and nested under the original file.--> <outputDirectoryForCss /> <!--Specifies a custom subfolder to save LESS files to. By default, compiled output will be placed in the same folder and nested under the original file.--> <outputDirectoryForLess /> <!--Specifies a custom subfolder to save SCSS files to. By default, compiled output will be placed in the same folder and nested under the original file.--> <outputDirectoryForScss /> </settings> <!--The order of the <file> elements determines the order of the images in the sprite.--> <files> <file>/Content/Images/01.png</file> <file>/Content/Images/02.png</file> <file>/Content/Images/03.png</file> <file>/Content/Images/04.png</file> </files> </sprite>
به عنوان مثال فایل CSS تصویر فوق به صورت زیر میباشد:
/* This is an example of how to use the image sprite in your own CSS files */ .Content-Images-01 { /* You may have to set 'display: block' */ width: 32px; height: 32px; background: url('icons.png') 0 0; } .Content-Images-02 { /* You may have to set 'display: block' */ width: 32px; height: 32px; background: url('icons.png') 0 -32px; } .Content-Images-03 { /* You may have to set 'display: block' */ width: 32px; height: 32px; background: url('icons.png') 0 -64px; } .Content-Images-04 { /* You may have to set 'display: block' */ width: 32px; height: 32px; background: url('icons.png') 0 -96px; }
<div class="Content-Images-01"></div> <div class="Content-Images-02"></div> <div class="Content-Images-03"></div> <div class="Content-Images-04"></div>
استفاده از تصاویر Data URIs
یکی دیگر از روشهای کاهش درخواستهای HTTP در یک سایت استفاده از Data URIs می باشد، توسط این روش میتوانید فایل هایتان را درون HTML و یا CSS قرار دهید یا به اصطلاح embed کنید. به طور مثال جهت استفاده از یک تصویر میتوانید به راحتی با آدرس دهی تصویر درون تگ img، تصویر را درون صفحه نمایش دهید:
<img src="https://www.dntips.ir/images/logo.png" />
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC" />
سینتکس Data URIs
به طور مثال تگ زیر را در نظر داشته باشید:
<img src="data:image/png;base64,iVBOR..." />
data: نام schema
image/png: نوع محتوا(content type)
base64: نوع encoding استفاده شده برای encode کردن اطلاعات
iVBOR...: اطلاعات encode شده.
توسط افزونه Web Essentials به راحتی میتوانید تصویر موردنظرتان را به صورت Data URI تهیه کنید:
اشتراکها
قوانین UX
اشتراکها
رابطهی بین قهوه و توسعه دهندهها
We are proud to present the first beta release of Kendo UI for Angular 2. It’s been designed specifically for Angular 2. Written in Typescript, built as native Query-free components and distributed as NPM packages, Kendo UI for Angular 2 makes integrating UI components into ng2 a piece of cake for developers. In this beta release, you’ll find the business application essential building blocks — form elements, grid and data visualization components.
- Update extension to handle upcoming breaking change to launch.json configurations in VS Code 1.28.
- Fixed launch.json
envFile
option on Windows - Fixed a bug where OmniSharp flame was red inspite of OmniSharp loading the projects without any errors.
- Fixed a problem with tracking virtual documents from other providers