همچنین مزیت دیگر آن، انتقال سادهتر کدهای جاوا به سیشارپ است؛ از این لحاظ که ویژگی مشابهی در زبان جاوا تحت عنوان «Default Methods» سالها است که وجود دارد.
یک مثال از ویژگی «پیاده سازیهای پیشفرض در اینترفیسها»
interface ILogger { void Log(string message); } class ConsoleLogger : ILogger { public void Log(string message) { Console.WriteLine(message); } }
مدتی بعد بر اساس نیازمندیهای مشخصی به این نتیجه خواهید رسید که بهتر است overload دیگری را برای متد Log در اینترفیس ILogger، درنظر بگیریم. مشکلی که این تغییر به همراه دارد، کامپایل نشدن کلاس ConsoleLogger در یک برنامهی ثالث است و این کلاس باید الزاما این overload جدید را پیاده سازی کند؛ در غیراینصورت قادر به کامپایل برنامهی خود نخواهد شد. اکنون در C# 8.0 میتوان برای این نوع تغییرات، در همان اینترفیس اصلی، یک پیاده سازی پیشفرض را نیز قرار داد:
interface ILogger { void Log(string message); void Log(Exception exception) => Console.WriteLine(exception); }
ویژگی «پیاده سازیهای پیشفرض در اینترفیسها» چگونه پیاده سازی شدهاست؟
واقعیت این است که امکان پیاده سازی این ویژگی، سالها است که در سطح کدهای IL دات نت وجود داشته (از زمان دات نت 2) و اکنون از طریق کدهای برنامه با بهبود کامپایلر آن، قابل دسترسی شدهاست.
تاثیر زمینهی کاری بر روی دسترسی به پیاده سازیهای پیشفرض
مثال زیر را درنظر بگیرید:
interface IDeveloper { void LearnNewLanguage(string language, DateTime dueDate); void LearnNewLanguage(string language) { // default implementation LearnNewLanguage(language, DateTime.Now.AddMonths(6)); } } class BackendDev : IDeveloper // compiles OK { public void LearnNewLanguage(string language, DateTime dueDate) { // Learning new language... } }
سؤال: به نظر شما اکنون کدامیک از کاربردهای زیر از کلاس BackendDev، کامپایل میشود و کدامیک خیر؟
IDeveloper dev1 = new BackendDev(); dev1.LearnNewLanguage("Rust"); var dev2 = new BackendDev(); dev2.LearnNewLanguage("Rust");
There is no argument given that corresponds to the required formal parameter 'dueDate' of 'BackendDev.LearnNewLanguage(string, DateTime)' (CS7036) [ConsoleApp]
ارثبری چندگانه چطور؟
احتمالا حدس زدهاید که این قابلیت ممکن است ارثبری چندگانه را که در سیشارپ ممنوع است، میسر کند. تا C# 8.0، یک کلاس تنها از یک کلاس دیگر میتواند مشتق شود؛ اما این محدودیت در مورد اینترفیسها وجود ندارد. به علاوه تاکنون اینترفیسها مانند کلاسها، امکان تعریف پیاده سازی خاصی را نداشتند و صرفا یک قرارداد بیشتر نبودند. بنابراین اکنون این سؤال مطرح میشود که آیا میتوان با ارائهی پیاده سازی پیشفرض متدها در اینترفیسها، ارثبری چندگانه را در سیشارپ پیاده سازی کرد؛ مانند مثال زیر؟!
using System; namespace ConsoleApp { public interface IDev { void LearnNewLanguage(string language) => Console.Write($"Learning {language} in a default way."); } public interface IBackendDev : IDev { void LearnNewLanguage(string language) => Console.Write($"Learning {language} in a backend way."); } public interface IFrontendDev : IDev { void LearnNewLanguage(string language) => Console.Write($"Learning {language} in a frontend way."); } public interface IFullStackDev : IBackendDev, IFrontendDev { } public class Dev : IFullStackDev { } }
IFullStackDev dev = new Dev(); dev.LearnNewLanguage("TypeScript");
The call is ambiguous between the following methods or properties: 'IBackendDev.LearnNewLanguage(string)' and 'IFrontendDev.LearnNewLanguage(string)' (CS0121)
تفاوت امکانات کلاسهای Abstract با متدهای پیشفرض اینترفیسها چیست؟
اینترفیسها هنوز نمیتوانند مانند کلاسها، سازندهای را تعریف کنند. نمیتوانند متغیرها/فیلدهایی را در سطح اینترفیس داشته باشند. همچنین در اینترفیسها همهچیز public است و امکان تعریف سطح دسترسی دیگری وجود ندارد.
بنابراین باید بخاطر داشت که هدف از تعریف اینترفیسها، ارائهی «یک رفتار» است و هدف از تعریف کلاسها، ارائه «یک حالت».
یک نکته: در نگارشهای پیش از C# 8.0 هم میتوان ویژگی «متدهای پیشفرض» را شبیه سازی کرد
واقعیت این است که توسط ویژگی «متدهای الحاقی»، سالها است که امکان افزودن «متدهای پیشفرضی» به اینترفیسها در زبان سیشارپ وجود دارد:
namespace MyNamespace { public interface IMyInterface { IList<int> Values { get; set; } } public static class MyInterfaceExtensions { public static int CountGreaterThan(this IMyInterface myInterface, int threshold) { return myInterface.Values?.Where(p => p > threshold).Count() ?? 0; } } }
var myImplementation = new MyInterfaceImplementation(); // Note that there's no typecast to IMyInterface required var countGreaterThanFive = myImplementation.CountGreaterThan(5);
We're going to use Dapper.NET on our project; that much is not in doubt. However, we're not going to start development with it, and it will not be the only ORM in use. The plan is to develop this project using Entity Framework, and later optimize to use Dapper.NET in certain scenarios where the system needs a performance boost.
Below is an illustration of how diffing works in Blazor (which copies React component model almost exactly):
Nebular is a great toolkit if you build Rich UI web-application based on Angular, and want to bootstrap your development using essential features out of the box. It provides you with a set of native Angular components, themeable components, authentication and security layers easily configurable for your API. At the same time, Nebular allows you to use it together with any other UI library you choose.
In development world, you may get a requirement from your client, they wants a weekly, quarterly and yearly charts. You always think, how can I make charts with use of angularjs. So today, in this article, we are going to learn
- how to create charts in angularjs using webapi
- higcharts.js
In this example, our requirement is, we have dropdownlist of student names. if user select any student, it will show selected students marks in the form of charts.