متدهای اپراتوری Explicit و Implicit
نام دوره: زبان سی شارپ مقدماتی
نویسنده: علی مقدم جاه (مدرس دوره)
متدهای اپراتوری Explicit و Implicit
در پست آموزش عملیات Explicit و Implicit، با مفهوم این دو اصطلاح آشنا شدهاید.
فرض کنید که دو کلاس به نامهای Student و Teacher به شکل زیر دارید:
class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public string StudentFamily { get; set; }
public void PrintStudentInfo()
{
Console.WriteLine($"Id: {StudentId}\tName: {StudentName}\tFamily: {StudentFamily}");
}
}
class Teacher
{
public int TeacherId { get; set; }
public string TeacherName { get; set; }
public string TeacherFamily { get; set; }
public int TeacherSalary { get; set; }
public void PrintTeacherInfo()
{
Console.WriteLine($"Id: {TeacherId}\tName: {TeacherName}\tFamily: {TeacherFamily}\tSalary: {TeacherSalary}");
}
}
همانطور که مشاهده میکنید، این دو کلاس هیچ مبحث وراثتی با هم نداشته و کاملا اعضاء داخل آنها به غیر از پراپرتی Salary با یکدیگر برابر هستند.
ابتدا از این دو کلاس، یک شئ یا نمونه به نامهای student1 و teacher1 در برنامه خود تعریف میکنیم:
Student student1 = new Student()
{
StudentId = 1,
StudentName = "Anahita",
StudentFamily = "Khosravi",
StudentPhonenumber = "09196177955"
};
Teacher teacher1 = new Teacher()
{
TeacherId = 10,
TeacherName= "Ali",
TeacherFamily="Moghadam Jah",
TeacherSalary=9500000
};
student1.PrintStudentInfo();
teacher1.PrintTeacherInfo();
حال اگر برنامه را اجرا کنیم، خروجی متدهای WriteLine بدون هیچ مشکلی به شکل زیر خواهند بود:
Id: 1 Name: Anahita Family: Khosravi Phone: 09196177955
Id: 10 Name: Ali Family: Moghadam Jah Phone: 09121234567
اما سوال پیش میآید که آیا امکان انتقال شئ student1 را درون teacher1 داریم؟
teacher1 = student1;
Error
قطعا این اتفاق شدنی نیست!
این درسته که ظرف teacher1 از ظرف student1 بزرگتر است، اما نوع دادههایشان بایکدیگر برابر نیستند!
همانطور که قبلا هم گفتیم، هر کلاس خود یک نوع دادهای است، درنتیجه student یک نوع داده و Teacher یه نوع داده دیگر است و چون این دو ظرف بایکدیگر از نظر نوع داده برابر نیستند، قطعا قطعه کد بالا در IDE خطا خواهد داد.
این اتفاق برای عملیات برعکس کد بالا نیز رخ خواهد داد:
student1= teacher1;
Error
در این حالت هم نوع دادههایشان باهم برابر نیست، چون ظرف student کوچکتر از ظرف teacher است!
درصورتی که نیاز دارید تا دو قطعه کد بالا که دارای Error بودند را در برنامه خود اجرا کنید، یعنی به زبان ساده یک دانشجو را به استاد و یا یک استاد را به دانشجو تبدیل کنید، باید از اپراتورهای Explicit و Implicit استفاده نمایید.
با نوشتن متدهای اپراتوری Explicit و Implicit در کلاسهای student و teacher، توانایی تبدیل اشیاء این دو کلاس به یکدیگر را برای آنها فراهم میکنید، درنتیجه دیگر قطعه کدهای بالا دارای Error نخواهد شد.
در حال حاضر ما دو کلاس داریم، که یکی از آنها بزرگتر است، یعنی کلاس Teacher که علت آن وجود پراپرتی Salary بوده از کلاس Student بزرگتر است.
نکته اول: در هنگام تعریف متدهای اپراتوری Explicit و Implicit، فراموش نکنید که در کلاس بزرگتر (مثل Teacher) باید متد را از جنس Explicit و در کلاس کوچتر (مثل Student) باید متد را از جنس Implicit تعریف کنید.
نکته دوم: حتما متدهای اپراتوری Explicit و Implicit باید از جنس static تعریف شوند.
نکته سوم: حتما باید بعد از کلمه Explicit یا Implicit، از کلمه operator استفاده نمایید.
نکته چهارم: نام این متدها باید حتما نام کلاسی باشد که قرار است به آن تبدیل شود!
نکته پنجم: ورودی متدهای Explicit و Implicit، یک شئ از همان کلاسی است که متد در آن تعریف میشود.
الف) متد اپراتوری Explicit
public static explicit operator Student(Teacher obj)
{
Student student = new Student()
{
StudentId = obj.TeacherId,
StudentName = obj.TeacherName,
StudentFamily = obj.TeacherFamily
};
return student;
}
ساختار متد اپراتوری Explicit به شکل فوق است که باید حتما درون محدوده بلاک کلاس بزرگتر یعنی Teacher نوشته شود.
با استفاده از این متد، ما میخواهیم که یک teacher (کلاس بزرگتر) را به یک student (کلاس کوچکتر) تبدیل کنیم، درنتیجه در وهله اول باید آن teacher که قرار است به student تبدیل شود را به عنوان ورودی به این متد ارسال کنیم. (منظور همان Teacher obj است.)
سپس در محدوده بلاک این متد، یک شئ از کلاس student تعریف کرده و تمامی پراپرتیهای آن را از دادههای داخل شئ obj که به عنوان ورودی به متد ارسال شده است، مقداردهی میکنیم.
درنتیجه یک شئ به نام student با همان مقادیر obj ساخته شده و در نهایت با استفاده از کلمه Return به محل فراخوانی متد، شئ student را ارسال میکنیم.
پس چون کلاس Teacher از کلاس Student بزرگتر بوده است، متد نوشته شده درون آن را از نوع Explicit تعریف کردیم، و حالا میتوانیم بدون هیچ مشکلی به برنامه خود بازگشته و عمل تبدیل یک شئ از کلاس Teacher را به یک شئ از نوع Student انجام دهیم:
student1= teacher1;
این دستور تا قبل از نوشتن متد اپراتوری Explicit در کلاس Teacher دارای Error بود، اما الان که متد Explicit را تعریف کردهایم، میتوانیم بدون هیچ محدودیتی عمل Type Casting را به شکل زیر انجام دهیم:
student1= (Student)teacher1;
همانطور که در قطعه کد بالا مشاهده میکنید، ابتدا با استفاده از عبارت (Student)، سیستم شئ teacher1 را به یک شئ از کلاس Studnent تبدیل کرده و سپس درون ظرف student1 قرار میدهد.
متد اپراتوری Implicit
متد Implicit دقیقا برعکس متد Explicit بوده و باید حتما در کلاس کوچکتر نوشته شود، مابقی موارد و نکتهها در هر دو متد بایکدیگر برابر بوده و تفاوتی باهم نداشته و میتوانیم به همان شکل بالا تعریف کنیم، با این تفاوت که اینبار از کلمه Implicit استفاده میکنیم:
public static Implicit operator Teacher(Student obj)
{
Teacher teacher = new Teacher()
{
TeacherId = obj.StudentId,
TeacherName = obj.StudentName,
TeacherFamily = obj.StudentFamily,
TeacherSalary=0
};
return teacher;
}
همانطور که در ابتدای تعریف کلاسها مشاهده نمودید، کلاس Teacher دارای ۴ پراپرتی و کلاس Student دارای ۳ پراپرتی بود، برای همین در متد Explicit پراپرتی چهارمی وجود نداشت و سیستم مقدار داخل آن را اصلا در شئ return شده از نوع student حساب نمیکرد.
اما در متد Implicit ما میخواهیم شئ obj که از نوع student با ۳ پراپرتی است را درون شئ teacher با ۴ پراپرتی قرار دهیم، پس حتما باید پراپرتی چهارم (همان Salary) دارای مقدار باشد و نمیتوانیم از Null استفاده کنیم، برای همین ما از مقدار ۰ که یک مقدار بی اثر است برای مقداردهی این پراپرتی استفاده میکنیم.
حالا میتوانیم در برنامه خود به راحتی یک student را به یک Teacher بدون هیچ محدودیتی تبدیل کنیم:
teacher1= student1;
قطعه کد بالا بدون هیچ مشکلی کار کرده و شئ student1 را درون teacher1 مقداردهی میکند.
نکته بسیار مهم: در تبدیل کلاس بزرگتر به کلاس کوچکتر، حتما باید عمل Type Cast انجام شود، به همین علت ما از کد زیر استفاده کردیم:
student1= (Student)teacher1;
یعنی ابتدا teacher1 را به student تبدیل کرده و سپس درون ظرف student1 قرار میدهیم.
اما در هنگام تبدیل یک کلاس کوچکتر به یک کلاس بزرگتر، دیگر نیازی به عمل Type Cast نبوده و به راحتی میتوانیم به شکل زیر عملیات تبدیل را انجام دهیم:
teacher1= student1;
جهت شرکت در دورههای زبان برنامه نویسی سیشارپ، از کد تخفیف heplc30 استفاده کنید.