PDA

View Full Version : شی گرا ورژن یک



alireza_tavakol
جمعه 06 مهر 1386, 01:02 صبح
دوستان عزیز سلام بازم من گیر کردم
در زبان ++C مبحثی موجود بود با نام توابع دوست کلاس Frend
موضوع از این قرار بود که شما خط تعریف تابع رو که در کلاستون قرار می دادید و قبلش کلمه Frend رو مینوشتید
از اون به بعد اون تابع ، دوست کلاس ساخته شده معرفی می گشت
و حسن این عمل این بود که در تابع دوست کلاس به تمام متد های کلاس دسترسی داشتید حتی private
حالا سوال من اینه که در زبان #C چه طوری میتونم تابعی رو دوست یک کلاس معرفی کنم ؟

hassan razavi
جمعه 06 مهر 1386, 02:00 صبح
می تونید از ویژگی Protected برای این منظور استفاده کنید

alireza_tavakol
جمعه 06 مهر 1386, 02:13 صبح
متدی که Protected تعریف میشه در کلاسی فرزند قابل دسترس است
در صورتی که کلاس من sealed تعریف شده و اصلا امکان ارث بری از طرف کلاس های دیگر را ندارد

PC2st
جمعه 06 مهر 1386, 22:33 عصر
میتونید از Nested Class ها استفاده کنید، مثلا:


class MainClass
{
private int _hiddenValue;
public class NestedClass
{
MainClass _mainClass;
public NestedClass()
{
this._mainClass = new MainClass();
}
public int ChangeValue()
{
this._mainClass._hiddenValue = 10;
return this._mainClass._hiddenValue;
}
}
public class InheritedNestedClass : MainClass
{
public override int ChangeValue()
{
this._hiddenValue = 20;
return this._hiddenValue;
}
}
public virtual int ChangeValue()
{
this._hiddenValue = 5;
return this._hiddenValue;
}
}

برای مشخص شدن طرز کار کرد، دستورات زیر رو اجرا کنید:


MainClass mainClass = new MainClass();
MainClass.NestedClass friendClass1 = new MainClass.NestedClass();
MainClass.InheritedNestedClass friendClass2 = new MainClass.InheritedNestedClass();
Console.WriteLine("The _hiddenValue member is a private field.");
Console.WriteLine();
Console.WriteLine("Changed from:\tMainClass\n\n\tIt value is: {0}\n", mainClass.ChangeValue());
Console.WriteLine("Changed from:\tNestedClass\n\n\tIt value is: {0}\n", friendClass1.ChangeValue());
Console.WriteLine("Changed from:\tInheritedNestedClass\n\n\tIt value is: {0}\n", friendClass2.ChangeValue());
Console.ReadKey();

کلاسهای NestedClass و InheritedNestedClass به عضو private از کلاس MainClass دسترسی دارند.

یادمه این اولین سوالی بود که در این فروم پرسیدم و جناب "آرژنگ" پاسخش رو دادند :لبخند:

mohammad272005
شنبه 07 مهر 1386, 01:44 صبح
با Reflection، به همه اعضاء دسترسی داری. یه بار (typeof(ClassName رو امتحان کن. اگه خواستی یه سورس کوچولو هم بهت می‏دم.

alireza_tavakol
شنبه 07 مهر 1386, 02:47 صبح
نیکی و پرسش؟
یه دنیا شرمندت میشم که
یه سورس کوچولو هم بهم بدی.

hdv212
شنبه 07 مهر 1386, 04:03 صبح
حالا سوال من اینه که در زبان #C چه طوری میتونم تابعی رو دوست یک کلاس معرفی کنم ؟
فکر کنم از واژه ی کلیدی internal باید اسفاده کنید.

alireza_tavakol
شنبه 07 مهر 1386, 16:14 عصر
من نفهمیدم منظورتون از internal چیه لطفا یه مثال بزنید

alireza_tavakol
شنبه 07 مهر 1386, 16:24 عصر
کلاسهای NestedClass و InheritedNestedClass به عضو private از کلاس MainClass دسترسی دارند.
عزیزم PC2st.ir یه دنیا ممنون از پاسخ واضح شما ولی
من گفتم کلاسی دارم که یه متدی یا خصوصیتی دارد با سطح دسترسی private تا حالا مثال شما این گزینه رو داشت ولی
کلاسی که مد نظر من بود گفتم از نوع sealed تعریف شده و امکان تعریف کلاس فرزند وارث بری برای دیگران را ندارد اما در مثال شما یکی از کلاس های تعریف شده از کلاس اصلی ارث بری مینمود
و در نهایت من قرار است از یک کلاس دیگر که هیچ ارتباطی با کلاس اصلی ندارد (نه این که زیر کلاس اصلی باشد) به یکی از متد ها یا خصوصیات private دسترسی پیدا کنم
پیشا پیش از پاسخ شما کمال تشکر را بجا میآورم

PC2st
شنبه 07 مهر 1386, 19:41 عصر
کلاس InheritedNestedClass رو از کلاس MainClass به ارث رسوندم، برای اینکه ببینید در صورت ارث بری میشه به عضو private از کلاس پدر هم دسترسی داشت وگرنه الزامی نیست که کلاس والد رو بصورت sealed تعریف نکینم، شما میتونید یک کلاس رو بصورت sealed تعریف کنید بصورتی که یک کلاس Nested هم داشته باشه.

اگر میخواید که به اعضای مخفی کلاس A از کلاس B دسترسی داشته باشید، باید کلاس B رو بصورت کلاس داخلی در کلاس A تعریف کنید.

یک مثال از کلاس sealed که کلاس دیگری به اعضای private آن دسترسی دارد:


sealed class MainClass
{
private int _hiddenValue;
public int HiddenValue
{
get { return this._hiddenValue; }
}
public class NestedClass
{
MainClass obj;
public NestedClass(MainClass obj)
{
this.obj = obj;
}
public int HiddenValue
{
get { return this.obj._hiddenValue; }
set { this.obj._hiddenValue = value; }
}
}
}

استفاده:


MainClass main = new MainClass();
Console.WriteLine(main.HiddenValue);
MainClass.NestedClass nested = new MainClass.NestedClass(main);
nested.HiddenValue = 20;
Console.WriteLine(main.HiddenValue);
Console.ReadKey();

اگر به کدهای فوق دقت کنید، مقدار فیلد hiddenValue_ از کلاس MainClass توسط این کلاس قابل تغییر نیست ولی میتوان این فیلد را از طریق کلاس NestedClass تغییر داد. (خاصیت main.HiddenValue از نوع فقط خواندنی است ولی خاصیت nested.HiddenValue هم خواندنی و هم نوشتنی است) همچنین نمیشه از کلاس MainClass به ارث رسوند.

alireza_tavakol
یک شنبه 08 مهر 1386, 16:43 عصر
این طوری که من از پاسخ شما متوجه شدم فهمیدم که
امکان دسترسی به اعضای private یک کلاس از کلاسی که هیچ ربطی با آن کلاس ندارد ممکن نیست
پس مبحث تابع دوست کلاس در زبان ++C در زبان #C پیادهن سازی نشده است

PC2st
یک شنبه 08 مهر 1386, 20:41 عصر
پس مبحث تابع دوست کلاس در زبان ++C در زبان #C پیادهن سازی نشده است
بله، همینطوره... :-)

mohammad272005
پنج شنبه 12 مهر 1386, 03:16 صبح
کاش همون شبی که گفتم
اگه خواستی یه سورس کوچولو هم بهت می‏دمواست سورس رو می‏نوشتم. چون الان VS ندارم. مبحث Reflection بزرگه. ولی خلاصة خلاصش اینه که از روی "نوع" و شیء" ساخته شده از اون نوع، شما به تمام اعضاءش دسترسی داشته‏باشی. حالا این یعنی چی؟
فرض کن کلاسی به صورت زیر داشته باشی:

class ClassName
{
private int property
{
get{...}
set{...}
}
private methods()
{...}
}
بعد از روش یه Instance بگیری:

ClassName className = new ClassName()
حالا برای بدست آوردن propertyهاش باید اینکارو بکنی:

foreach(PropertyInfo prop in className.GetType().GetProperties())
Console.WriteLine(prop.Name, prop.GetValue(className, null);
و برای اجرای متدهاش:


foreach(MethodInfo method in className.GetType().GetMethods())
Console.WriteLine(method.Name, prop.Invoke(className, null);
این کدها را کاملا حفظی نوشتن چون VS ندارم. مسلما بدون اشکال نیست.

PC2st
پنج شنبه 12 مهر 1386, 05:41 صبح
خلاصش اینه که از روی "نوع" و شیء" ساخته شده از اون نوع، شما به تمام اعضاءش دسترسی داشته‏باشی.
فکر نمیکنم بشه به اعضای private دسترسی داشت... :متفکر:

mohammad272005
پنج شنبه 12 مهر 1386, 08:01 صبح
فکر نمیکنم بشه به اعضای private دسترسی داشت... :متفکر:به تمام اعضاء بلااستثناء می‏شه دسترسی داشت.

PC2st
پنج شنبه 12 مهر 1386, 12:38 عصر
به تمام اعضاء بلااستثناء می‏شه دسترسی داشت.
اگر میشه یک مثال مختصر برای اعضای private بزنید؟

PC2st
سه شنبه 17 مهر 1386, 20:20 عصر
اگر میشه یک مثال مختصر برای اعضای private بزنید؟
داشتم کارهای دیگه ای رو انجام میدادم که به یاد این تاپیک (نه چندان قدیمی) افتادم :-)
بعد چند دقیقه جستجو (در sample های MSDN) دیدم اینکار امکان پذیره و فقط باید BindingFlags تنظیم بشه...
نمونه مثال زیر رو نوشتم، شاید کسی لازم داشت:


using System;
using System.Reflection;

class Test { int _ID; string _Name; }

class Simple {
static void Main() {
Type type1 = typeof(Test);
FieldInfo[] fields = type1.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

foreach(FieldInfo field in fields)
Console.WriteLine("[" + field.Name + "]\tis a private field of [" + type1.Name + "] class.");

Console.ReadKey();
}
}

چون توسط Reflection، میتوان به هر عضو private از هر کلاسی دست یافت، پس سطوح دسترسی (private, protected, public و ...) بی معنا خواهد شد. در اینصورت، استفاده از Reflection کلاس Friend رو شبیه سازی نمی کند.

mohammad272005
چهارشنبه 18 مهر 1386, 04:35 صبح
مشکل حل شد؟

PC2st
چهارشنبه 18 مهر 1386, 04:50 صبح
مشکل حل شد؟


مشکل من؟! :-)

داشتم کارهای دیگه ای رو انجام میدادم که به یاد این تاپیک (نه چندان قدیمی) افتادم :-)
بعد چند دقیقه جستجو (در sample های MSDN) دیدم اینکار امکان پذیره و فقط باید BindingFlags تنظیم بشه...
فکر کنم حل شد.

mohammad272005
چهارشنبه 18 مهر 1386, 05:50 صبح
مشکل من؟! :-)
نه دوست من. شما که خودت حلال مشکلاتی. من منظور مشکل تاپیکه. من اومدم ببینم تو این تاپیک چه خبر که دیدم شما هم جواب مد نظر منو دادی.
با تشکر