|
مقاله ی اصلی:
Developer
گرانبار کردن
عملگر ها راهی برای
تعریف عملگر هایی
مانند +، -، * یا / مخصوص
کلاس یا ساختار
تعریف شده توسط
کاربر می باشد. همان
طور که C++ کار ها می
دانند، این کار به
خصوص در نوشتن کلاس
هایی مانند int یا string
استفاده ی زیادی
دارد در حالی که Java
فاقد این قابلیت می
باشد. گرانبار کردن
عملگر ها چیزی جز
نوشتن یک متد ساده
نیست. به طور کلی سه
نوع عملگر داریم:
عملگر های یگانی،
دودویی و تبدیلی.
1. عملگر های
یگانی:
این عملگر ها
فقط یک پارامتر می
گیرند مانند ++، =*، !، / یا
true. قواعد گرانبار
کردن عملگرهای
یگانی به صورت زیر می
باشد:
1. +، -، ! یا ~ باید
پارامتری از نوع
تعریف شده بگیرند و
می توانند هر نوعی را
برگردانند.
2. ++ یا -- باید
پارامتری از نوع
تعریف شده بگیرند و
همان نوع را
برگردانند.
3. true یا false باید
پارامتری از نوع
تعریف شده بگیرند و
یک bool برگردانند.
مثال زیر، به
سادگی گران بار کردن
عملگر های یگانی ++ و --
را نشان می دهد:
using System;
namespace OperatorOverloading
{
/// <remarks>
/// Class that implements a simple
counter.
/// </remarks>
public class MyCounter
{
private int _counter = 0;
/// <value>Get or set the counter
value</value>
public int CounterValue
{
get
{
return this._counter;
}
set
{
this._counter = value;
}
}
/// <summary>
/// Constructor
/// </summary>
/// <param name ="InitialValue">Initial
counter value</param>
public MyCounter(int InitialValue)
{
this.CounterValue = InitialValue;
}
/// <summary>
/// Increment the counter by one.
/// </summary>
/// <param name = "Counter">Counter to
increment</param>
/// <returns>Incremented
counter</returns>
public static MyCounter operator
++(MyCounter Counter)
{
Counter.CounterValue++;
return Counter;
}
/// <summary>
/// Decrement the counter by one.
/// </summary>
/// <param name = "Counter">Counter to
decrement</param>
/// <returns>Decremented
counter</returns>
public static MyCounter operator
--(MyCounter Counter)
{
Counter.CounterValue--;
return Counter;
}
}
}
نحوه ی استفاده
از کلاس بالا به صورت
زیر می باشد:
MyCounter count = new MyCounter(5);
Console.WriteLine(count.CounterValue);
count++;
Console.WriteLine(count.CounterValue);
2. عملگر های دو
دویی:
عملگر های
دودویی عملگرهایی
هستند که نیاز به دو
پارامتر دارند و
حداقل یکی از این دو
پارامتر باید از نوع
تعریف شده (آن کلاسی
که عملگر در آن
گرانبار می شود) باشد.
عملگر های +، -، *، /، %، &،
|، ^، <<، >>، ==، !=، >، <، => و =<
از این دسته می
باشند.
این مثال پیاده
سازی عملگر های > و < را
روی کلاسی برای نگه
داری نمره ی امتحان
نشان می دهد. در این
مثال گرانبار کردن
عملگر ها به ما اجازه
می دهد بدون مقایسه ی
جداگانه ی نمرات، آن
ها را با هم مقایسه
کنیم:
using System;
namespace OperatorOverloading
{
/// <remarks>
/// Class representing a standardized test whose
score is
/// comprised of the scores from various
sections.
/// </remarks>
public class StandardizedTest
{
private int _MathScore = 0;
private int _Reading = 0;
private int _Science = 0;
/// <value>Get or set the math
score</value>
public int MathScore
{
get
{
return this._MathScore;
}
set
{
this._MathScore = value;
}
}
/// <value>Get or set the reading
score</value>
public int Reading
{
get
{
return this._Reading;
}
set
{
this._Reading = value;
}
}
/// <value>Get or set the science
score</value>
public int Science
{
get
{
return this._Science;
}
set
{
this._Science = value;
}
}
/// <summary>
/// Constructor
/// </summary>
/// <param name = "math">Math
score</param>
/// <param name = "reading">Reading
score</param>
/// <param name = "science">Science
score</param>
public StandardizedTest(int math,
int reading, int science)
{
this.MathScore = math;
this.Reading = reading;
this.Science = science;
}
/// <summary>
/// Determine if the first test score is
greater.
/// </summary>
/// <param name ="score1"></param>
/// <param name ="test2"></param>
/// <returns></returns>
public static bool operator >(StandardizedTest score1,
StandardizedTest score2)
{
if ((score1.MathScore + score1.Reading + score1.Science) >
(score2.MathScore + score2.Reading + score2.Science))
{
return true;
}
return false;
}
/// <summary>
/// Determine if the first test score is
less.
/// </summary>
/// <param name ="score1"></param>
/// <param name ="test2"></param>
/// <returns></returns>
public static bool operator <(StandardizedTest score1,
StandardizedTest score2)
{
if ((score1.MathScore + score1.Reading + score1.Science) <
(score2.MathScore + score2.Reading + score2.Science))
{
return true;
}
return false;
}
}
}
کد زیر با
استفاده از مثال
صفحه ی فبل نمرات
امتحانی دو دانش
آموز را مقایسه می
کند:
StandardizedTest student1 = new StandardizedTest(200, 400, 400);
StandardizedTest student2 = new StandardizedTest(400, 400, 400);
if (student1 > student2)
{
Console.WriteLine("Student1 performed better");
}
else
{
Console.WriteLine("Student1 did not do better");
}
3. عملگر های
تبدیلی:
عملگر تبدیلی
هنگام انتساب یا رد
کردن آرگومان یا... که
نیاز به تبدیل نوعی
به نوع دیگر دارد،
گرانبار می شود. در C#
دو نوع عملگر تبدیلی
داریم: ضمنی و صریح. در
تبدیل ضمنی، یک نوع
داده ای را مستقیما
به نوع دیگر نسبت می
دهیم ولی در تبدیل
صریح، یک نوع باید
صریحا با عملگر قالب
ریزی (نام نوع مقصد در
میان پرانتز) به نوعی
دیگر تبدیل شود.
کلاس زیر فرمت های
مختلف فایل را نشان
می دهد که می توانند
به بک برنامه منتقل
شوند. گرانبار کردن
تبدیل یک رشته برای
این کلاس به ما اجازه
می دهد بدون استفاده
از پروپرتی های
کلاس، یک رشته را به
آن نسبت بدهیم. این
عمل به ویژه هنگام
کار با بانک
اطلاعاتی بسیار کار
آمد است:
using System;
namespace OperatorOverloading
{
/// <remarks>
/// File formats may be comma delimited, positional,
or XML.
/// </remarks>
public class FileFormat
{
public const string COMMA_DELIMITED =
"C";
public const string POSITIONAL = "P";
public const string XML = "X";
private string _FileFormatValue;
/// <value>Get or set the file format
value</value>
public string FileFormatValue
{
get
{
return this._FileFormatValue;
}
set
{
if (value.Equals(FileFormat.COMMA_DELIMITED) || value.Equals(FileFormat.POSITIONAL) || value.Equals(FileFormat.XML))
{
this._FileFormatValue = value;
}
}
}
/// <summary>
/// Constructor
/// </summary>
public FileFormat()
{
this._FileFormatValue = "";
}
/// <summary>
/// Implicitly convert from a string to
FileFormat.
/// </summary>
/// <param name = "v_Value">Value to
convert</param>
/// <returns>FileFormat</returns>
public static implicit operator FileFormat(string v_Value)
{
FileFormat f = new FileFormat();
f.FileFormatValue = v_Value;
return f;
}
}
}
از کلاس FileFormat به این
صورت می توان
استفاده کرد:
string dbFileFormat = "C"; //
Assume this is from database
FileFormat fileFormat = new FileFormat();
fileFormat = dbFileFormat;
گرانبار کردن
عملگر های تبدیلی
صریح مانند ضمنی می
باشد با این تفاوت که
کلمه ی implicit به explicit تبدیل
می شود و از آن به صورت
زیر استفاده می شود:
string dbFileFormat = "C"; //
Assume this is from database
FileFormat fileFormat = new FileFormat();
fileFormat = (FileFormat)dbFileFormat;
4. چند نکته:
برای استفاده
از ] و [ در یک کلاس
(مانند آرایه ها) می
توان به این صورت عمل
کرد:
using System;
namespace OperatorOverloading
{
/// <remarks>
/// Custom class for keeping dynamic memory like
array.
/// </remarks>
public class MyArray
{
private int[] _Array;
/// <summary>
/// Constructor
/// </summary>
public FileFormat()
{
this._Array = {0, 0, 0, 0, 0, 0, 0, 0};
}
/// <value>Get or set the array
values</value>
public int this[int index]
{
get
{
return this._Array[index];
}
set
{
this._Array[index] = value;
}
}
/// <value>Get or set length of the
array</value>
public int Length
{
get
{
return this._Array.Length;
}
set
{
this._Array = new int[value];
}
}
}
}
دقت کنید که
پارامتر ورودی (index) و
نوع بازگشتی می
تواند هر نوعی باشد.
C# اجازه ی
گرانبار کردن عملگر
انتساب را مانند C++
نمی دهد. در C++ دلیل
اصلی گرانبار کردن
انتساب، وجود اشاره
گر هاست در حالی که C#
به جز در مواقع
استفاده از بلوک unsafe
قابلیت استفاده از
اشاره گر ها را
ندارد.
عملگر ++ و -- را
برای پس افزایش می
توان گرانبار کرد
ولی برای پیش افزایش
مانند C++ نمی توان آن
را گرانبار کرد. لطفا
اگر کسی می داند چه
طوری می توان این کار
را انجام داد، با Email
اطلاع دهد تا با نام و
دیگر اطلاعات خودش
در همین قسمت قرار
گیرد.
|
IP: 38.107.191.103 |
Country: United States
|
Browser: Unknown |
OS: Unknown |
|
|