PDA

View Full Version : سوال: boxing / unboxing



ali_up1
یک شنبه 10 شهریور 1392, 09:37 صبح
سلام دوستان
کسی میدونه boxing چطوری پیاده سازس شده؟؟
خیلی سرچ زدم ولی solution پیاده سازی Boxing رو پیاده نکردم
ممنون دوستان

مهرداد صفا
یک شنبه 10 شهریور 1392, 14:30 عصر
با سلام.
اگر بخواهید مقدار یک drived class را در یک شی از base class قرار دهید همانطور که می دانید نیاز به هیچ عملگر خاصی نیست و این کار بدون خطا صورت می گیرد:


object x = "hello";
و اگر قصد داشته باشید مقدار base class را به derived class تبدیل یا unbox کنید، این کار به شکل زیر و بدون نیاز به پیاده سازی متود خاصی در کلاس فرزند امکان پذیر است:


MessageBox.Show((string)x);
البته در نظر داشته باشید که اگر مقداری که در x قرار دارد، یک string (و یا مقداری قابل تبدیل به آن) نباشد با خطای زمان اجرا روبرو خواهید شد.
اما اگر قصد داشته باشید مقداری از کلاس y را با استفاده از boxing در یک شی از کلاس x قرار دهید، باید عملگر explicit برای تبدیل x به y را در کلاس y سربار گذاری کنید.
همچنین اگر بخواهید مقداری از نوع x را در y آنباکس کنید باید عملگر implicit را در y سربار گذاری کنید.
در مثال زیر کلاسی به نام Test ایجاد شده است که:
- کار اصلی آن تبدیل اعداد تکرقمی به معادل متین آنهاست (مثلا "one" به جای 1) و بر عکس.
- دارای دو constructor است که یکی عدد و دیگری string می گیرد.
- دارای دو خصوصیت StringValue و IntegerValue است.
- قابلیت unbox شدن در رشته و int را دارد.
- مقدار آن می تواند از یک رشته و یا int باکس شود.



//بسم الله الرحمن الرحیم
//اللهم صل علی محمد و آل محمد

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication2
{
class Test
{
internal static Dictionary<int, string> MyDictionary = new Dictionary<int, string>() { { 1, "one"},
{0,"zero"},
{2,"two"},
{3,"three"},
{4,"four"},
{5,"five"},
{6,"six"},
{7,"seven"},
{8,"eight"},
{9,"nine"}};

public Test(int digit)
{
if(MyDictionary.ContainsKey(digit))
this._StringValue = MyDictionary[digit];
else
throw new ArgumentOutOfRangeException();
}

public Test(string text)
{
if (MyDictionary.ContainsValue(text))
this._IntegerValue=MyDictionary.Where(k=>k.Value==text).Select(k=>k.Key).First();
else
throw new ArgumentOutOfRangeException();
}


string _StringValue;
int _IntegerValue;

public string StringValue
{
get
{
return _StringValue;
}
}

public int IntegerValue
{
get
{
return _IntegerValue;
}
}

public static explicit operator Test(int number)
{
return new Test(number);
}

public static explicit operator Test(string value)
{
return new Test(value);
}
public static implicit operator int(Test value)
{
return value.IntegerValue;
}

public static implicit operator string(Test value)
{
return value.StringValue;
}

}
}



نمونه هایی از کاربرد:

Test y =(Test) 1;
int x =(Test) "one";
MessageBox.Show((Test)1);
MessageBox.Show((2+(Test)"three").ToString());

ali_up1
پنج شنبه 14 شهریور 1392, 12:14 عصر
مرسی مهرداد جان از توضیحات ات
ولی این توضیحات برای downCasting و upCasting نه boxing و unboxing
boxing/unboxing یعنی ریختن یه valueType به یه refreceType یا برعکس

FastCode
پنج شنبه 14 شهریور 1392, 15:22 عصر
http://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti