گفتگو هایی در باب سی شارپ

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
چون value type ئه.

سلامی مجدد استاد .
خیلی ممنون .

الان یعنی در کد زیر :

C#:
            ((string style, int? width, int? height)view, (bool? isRunInStartup, bool? isEnableSilentMode,
            (string driveName, bool? autoBackuping, int? autoBackupingValue)[] drivesBackupings, bool? isDisabledWindowsUpdate)model) settingTuples;

بجز آخرین لایه از پرانتز که مربوط به شیِ settingTuples که شی از از کلاس Tuple میشه هست ، بقیه ی جاهایی که (درونش) پرانتز داره ، یعنی مقادیری که به عنوان Item1 و Item2 و ... ، پرانتز دارن ، به عنوان شی ای از استراکچر هستن؟

یعنی قسمت زیر در کد بالا :

C#:
(string style, int? width, int? height)view

که مربوط به فیلدِ view (به عنوان Item1 ئه settingTuples) میشه ، یا قسمت زیر در کد بالا :

C#:
(bool? isRunInStartup, bool? isEnableSilentMode,
            (string driveName, bool? autoBackuping, int? autoBackupingValue)[] drivesBackupings, bool? isDisabledWindowsUpdate)model

که مربوط به فیلد model (به عنوان Item2 ئه settingTuples) میشه (این هایی که کلا با علامت پرانتز نوع شون تعریف میشه بجز لایه ی آخری که settingTuples هست) ، اینها از نوع استراکچر هستن و از نوع class نیستن؟

چون مشخصه یا indexer یا متد ای که مقدار value type ای مثل struct و tuple رو بر می گردونه داره یک کپی از مقدار رو بر میگردونه، ارجاع به مقدار اصلی نیست. برای همین نمی توانید فیلدی رو در مقدار برگشتی تغییر بدهید.
صورت مساله رو ساده می کنم. شما یک struct ساده مثل A رو در نظر بگیرید :
C#:
        struct A
        {
            public object Value;
        }
می توانید مقدار Value رو (نوع داده Value مهم نیست) در A ای که یک value type ئه اینطوری تغییر بدهید؟
C#:
            var a = new List<A>();
            a.Add(new A());
            a[0].Value = null;
نمی توانید. مشکل چیه؟ اون indexer در List به شما یک value type تحویل داده از نوع A که کپی مقدار اولین عضو لیست ئه.
و indexer اصلا متوجه نخواهد شد که شما با فیلد Value در اون داده کپی شده چه می کنید. شما هر بلایی سر اون داده کپی شده بیاورید تاثیری روی a[0] نمیذاره چون ارجاع به مقدار نیست، یک کپی از داده است. می خواهید Value چیزی رو تغییر بدهید که ربطی به اون عضو در لیست نداره.
برای همین کامپایلر جلوی انجام این عمل بی فایده رو میگیره.

بله . خیلی ممنون استاد .
این رو قبلا هم گفتید .
اما اون موقع ، دقیق متوجه نمیشدم .
الان که بیشتر روی این قضیه (پروپرتی و استراکچر) تمرکز میکنم ، ببینین مطالب زیر ام در این رابطه درسته؟ :
در کد زیر :

کد:
    public struct A
    {
        public object Value;
        public int Digit;

        public A(object val, int dig)
        {
            this.Value = val;
            this.Digit = dig;
        }
    }
   
   
   
    public class B
{
    private A _myVariable;
    public A MyVariable
    {
        get
        {
            return this._myVariable;
        }
        set
        {
            this._myVariable = value;
        }
    }
   
   
    public void Method1()
    {
            this.MyVariable = new A(null, 10);
            this.MyVariable.Digit = 20;
    }
}


وقتی خطِ this.MyVariable = new A(null, 10) در متد Method1 اجرا میشه ، قسمت set ئه پروپرتیِ MyVariable اجرا میشه .

همونطور که قبلا گفته بودین ، پروپرتی ها ، دقیقا مثل متد میمونن . یعنی هر قسمت (همون accessor) شون که اجرا میشه ، دقیق مثل زمانی که یه متد اجرا میشه ، در حافظه ی استکِ نخ مورد نظرشون ، حافظه ای (ولو موقتی) براشون اختصاص داده میشه برای اجرا (حالا دقیقا جریان حافظه ی اشغالی توسط متدها و اینکه حجم شون چقدر میشه و بر اساس چه چیزی حجم شون کم یا زیاد میشه و اینها را نمیدونم و ممنون میشم در این باره هم توضیح بدین) .

در قسمت set ئه این پروپرتی هم مقدار جدیدی در متغییر _myVariable میریزه (حافظه ی این متغییر هم چون از نوع استراکچر هست ، استراکچرها هم که گفته بدوید به اندازه ی فیلدهاشون حافظه اشغال میکنن . پس این متغییر در ویندوز 32 بیتی ، 64 بیت و در ویندوز 64 بیتی ، 96 بیت حافظه اشغال میکنه دیگه؟)

قسمت set ئه پروپرتی اش (مثل همه ی پروپرتی ها) ، هم چیزی را برنمیگردونه ، پس بعد از اجرا ، اشاره گر به حافظه اش از دست میره و دیگه نیازی نمیشه.

============

وقتی خط this.MyVariable.Digit = 20 در متد Method1 اجرا بشه (که البته ارور میده) ، با فراخونیِ this.MyVariable ، قسمت get ئه پروپرتی تا اینجا اجرا میشه . مثل متدها ، برای اجرای قسمت get ، حافظه ای بهش اختصاص داده میشه .
در کد این قسمت :

C#:
            get
            {
                return this._myVariable;
            }

تا زمانی که میره مقدار متغییر _myVariable را میخونه ، تا اینجا ، مستقیما به خونه ی مورد نظر در این متغییر رجوع میکنه و تا اینجا ، کپی کردنی صورت نمیگیره (من قبلا احتمالا فکر میکردم حتی وقتی نامِ متغییری از نوع استراکچر را که نام ببریم ، مقدارش را کپی میکنه) .

اما وقتی که در کد بالا ، return میکنیم ، داریم مقدارِ مورد نظر را در حافظه ی اون متدمون که در استکِ نخ مون در نظر گرفته شده بود ، ذخیره میکنیم و چون اینجا ، صرفا رجوع کردن نیست بلکه در حافظه ی جدیدِ دیگه ای (حافظه ی متدمون) داریم میریزیم ، پس زمانی که در متدمون (شامل پروپرتی یا ایندکسر) ، نوعِ استراکچر را return و ذخیره میکنیم ، کل مقدار استراکچرِ مورد نظر را کپی میکنه توی حافظه اش .

پس در قسمت get ئه این پروپرتی ، مقدارِ کپی شده (در حافظه ی جدید) از متغییرِ _myVariable را داریم .
وقتی هم که خط this.MyVariable.Digit = 20 اجرا بشه ، مقدار فیلد Digit را در حافظه ی کپی شده (که مقدار بازگشتیِ قسمتِ get ئه پروپرتی مون بود که منظورمون این حافظه نیست) ، تغییر میده ، نه اینکه مقدار فیلد Digit در حافظه ی متغییر _myVariable را تغییر بده .
مثل تصویر زیر :


1.JPG


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

C#:
            this.MyVariable = new A(null, 10);
            this.MyVariable.Digit = 20;

اما چون خط دوم ارور میده به دلایلی که گفته شد ، واسه ی همین از اجرای همچین کدی ، جلوگیری میشه .

------

من قبلا فکر میکردم که this._myVariable.Digit = 99 را هم که اجرا کنیم (دقت کنید که _myVariable ، نام فیلد هست ، نه نام پروپرتی) ، به صِرفِ اینکه نامِ فیلد هم برده بشه و زمانی که خونده هم میشه ، برابر با زمانی هست که return میشه و در حافظه ی دیگه ای ذخیره میشه که این ، درست نیست .

بلکه در این حالت (که نام فیلد فراخونی میشه) ، مستقیما به حافظه ی همون فیلد مراجعه میشه (اولین شکل در تصویر بالا که حافظه ی فیلد _myVariable هست) و دیگه کپی شدن (صِرفِ خوندنِ اون فیلد) ، معنا نداره .

درست گفتم استاد؟
تشکر
 

the_king

مدیرکل انجمن
سلامی مجدد استاد .
خیلی ممنون .

الان یعنی در کد زیر :

C#:
            ((string style, int? width, int? height)view, (bool? isRunInStartup, bool? isEnableSilentMode,
            (string driveName, bool? autoBackuping, int? autoBackupingValue)[] drivesBackupings, bool? isDisabledWindowsUpdate)model) settingTuples;
بجز آخرین لایه از پرانتز که مربوط به شیِ settingTuples که شی از از کلاس Tuple میشه هست ، بقیه ی جاهایی که (درونش) پرانتز داره ، یعنی مقادیری که به عنوان Item1 و Item2 و ... ، پرانتز دارن ، به عنوان شی ای از استراکچر هستن؟
کلاس tuple اینه :
که static ئه و طبعا شیء ای نمیتونه از کلاس static ایجاد بشه. و در ضمن کلاس ها reference type هستند، طبعا وقتی در توضیح tuple ها ذکر شده که value type هستند و توضیح دادم که دلیل اون خطا چیه، دیگه چه کلاسی؟
Tuple types are value types; tuple elements are public fields. That makes tuples mutable value types.
They are structures (value types) rather than classes (reference types).
یعنی قسمت زیر در کد بالا :

C#:
(string style, int? width, int? height)view

که مربوط به فیلدِ view (به عنوان Item1 ئه settingTuples) میشه ، یا قسمت زیر در کد بالا :

C#:
(bool? isRunInStartup, bool? isEnableSilentMode,
            (string driveName, bool? autoBackuping, int? autoBackupingValue)[] drivesBackupings, bool? isDisabledWindowsUpdate)model

که مربوط به فیلد model (به عنوان Item2 ئه settingTuples) میشه (این هایی که کلا با علامت پرانتز نوع شون تعریف میشه بجز لایه ی آخری که settingTuples هست) ، اینها از نوع استراکچر هستن و از نوع class نیستن؟
کدوم کلاس؟ چرا اصلا باید کلاسی باشه یا نباشه؟ چرا میگید "الان یعنی"؟ در پست قبلی اصلا حرفی در مورد کلاس نزدم که موضوع کلاس بودن و نبودن باشه.
وقتی خطِ this.MyVariable = new A(null, 10) در متد Method1 اجرا میشه ، قسمت set ئه پروپرتیِ MyVariable اجرا میشه .

همونطور که قبلا گفته بودین ، پروپرتی ها ، دقیقا مثل متد میمونن . یعنی هر قسمت (همون accessor) شون که اجرا میشه ، دقیق مثل زمانی که یه متد اجرا میشه ، در حافظه ی استکِ نخ مورد نظرشون ، حافظه ای (ولو موقتی) براشون اختصاص داده میشه برای اجرا (حالا دقیقا جریان حافظه ی اشغالی توسط متدها و اینکه حجم شون چقدر میشه و بر اساس چه چیزی حجم شون کم یا زیاد میشه و اینها را نمیدونم و ممنون میشم در این باره هم توضیح بدین) .
در مورد ماهیت get و set در مشخصه ها توضیح تون درسته اما من هیچ صحبتی از حافظه و نخ ای نکردم.
استک نخ مورد نظرشون نمیدونم چیه، اگه در مورد زبان سی شارپ حرف می زنید، استک نخ و حافظه اشغالی متد ها و ... از این حرف ها رو بریزید دور، وجود خارجی نداره. اگر هم میخواهید کارکرد CLR یا CoreCLR نسخه فلان رو تحلیل کنید، باید بروید سراغ مهندسی معکوس اش که نمیدونم اصلا به چه دردی میخوره، از نظر من دانستن این چیزها برای برنامه نویس دات نت بیخود ئه. مثل اینه که بخواهید بدونید در بین تریلیون ها سلول داخل بدن تون هر کدوم الان داره چیکار میکنه.
در قسمت set ئه این پروپرتی هم مقدار جدیدی در متغییر _myVariable میریزه (حافظه ی این متغییر هم چون از نوع استراکچر هست ، استراکچرها هم که گفته بدوید به اندازه ی فیلدهاشون حافظه اشغال میکنن . پس این متغییر در ویندوز 32 بیتی ، 64 بیت و در ویندوز 64 بیتی ، 96 بیت حافظه اشغال میکنه دیگه؟)
نمیدونم حافظه ها ساختار رو بر مبنای چه معیاری محاسبه می کنید اما من نه همچین حرف هایی زدم و نه در مورد میزان حافظه مصرفی یک ساختار داده مدیریت شده توضیحی دادم. باز زدید تو جاده خاکی. حرف های از اینجور مواردی است :
مستندات خاصی نداره که این ساختار رو مشخص کنه، از اون مباحثی است که برای اینجور زبان ها که ساختار حافظه اشیاء پنهانه دانستنش فایده عملی نداره.
اشکال کار همینجا است، مطلبی نیست که بدردی بخوره. اگه کسی ندونه که اشاره گری هست یا ندونه که تغییر میکنه یا نمیکنه هیچ فرقی بحالش نمی کنه. علمی که منفعتی در اون نباشه دانستنش هم بیخوده.
صحبت همون فیل ئه و خرطومه است. ما در زبان #C اشاره گری برای این متغیر که میگید نداریم، وقتی چیزی وجود نداره و در زبان تعریف نشده، در مورد جابجا شدن چه چیزی بدونیم؟
فرض کنید حافظه قبلی باشه، یا فرض کنید حافظه جدید باشه. هر دو فرض به یک اندازه بی معنی هستند. الان این قضیه فیل و خرطومش چقدر علمی و مفید بود؟ این فرض شما هم همونقدر علمی و مفید میشه.
اسناد مایکروسافت در مورد پیاده سازی GC در CLR ئه، جزئی از ماشین مجازی که NET. رو اجرا می کنه. اصلا در مورد زبان #C و NET. نیست. اینکه GC با چه ساختار حافظه ای پیاده سازی بشه ربطی به زبان #C نداره، همین الان هم GC در Mono با ساختار های متفاوتی پیاده سازی شده که ربطی به مستندات مایکروسافت هم نداره. بحث زبان #C رو با این موارد نامربوط قاطی نکنید.

.
قسمت set ئه پروپرتی اش (مثل همه ی پروپرتی ها) ، هم چیزی را برنمیگردونه ، پس بعد از اجرا ، اشاره گر به حافظه اش از دست میره و دیگه نیازی نمیشه.
وقتی خط this.MyVariable.Digit = 20 در متد Method1 اجرا بشه (که البته ارور میده) ، با فراخونیِ this.MyVariable ، قسمت get ئه پروپرتی تا اینجا اجرا میشه . مثل متدها ، برای اجرای قسمت get ، حافظه ای بهش اختصاص داده میشه .
اشاره گر به حافظه چی؟ کدوم اشاره گر؟ کدوم حافظه؟ چی میگید؟ در کدوم پست من دیدید از این حرف ها بزنم؟

.
در کد این قسمت :

C#:
            get
            {
                return this._myVariable;
            }

تا زمانی که میره مقدار متغییر _myVariable را میخونه ، تا اینجا ، مستقیما به خونه ی مورد نظر در این متغییر رجوع میکنه و تا اینجا ، کپی کردنی صورت نمیگیره (من قبلا احتمالا فکر میکردم حتی وقتی نامِ متغییری از نوع استراکچر را که نام ببریم ، مقدارش را کپی میکنه) .

اما وقتی که در کد بالا ، return میکنیم ، داریم مقدارِ مورد نظر را در حافظه ی اون متدمون که در استکِ نخ مون در نظر گرفته شده بود ، ذخیره میکنیم و چون اینجا ، صرفا رجوع کردن نیست بلکه در حافظه ی جدیدِ دیگه ای (حافظه ی متدمون) داریم میریزیم ، پس زمانی که در متدمون (شامل پروپرتی یا ایندکسر) ، نوعِ استراکچر را return و ذخیره میکنیم ، کل مقدار استراکچرِ مورد نظر را کپی میکنه توی حافظه اش .

پس در قسمت get ئه این پروپرتی ، مقدارِ کپی شده (در حافظه ی جدید) از متغییرِ _myVariable را داریم .
وقتی هم که خط this.MyVariable.Digit = 20 اجرا بشه ، مقدار فیلد Digit را در حافظه ی کپی شده (که مقدار بازگشتیِ قسمتِ get ئه پروپرتی مون بود که منظورمون این حافظه نیست) ، تغییر میده ، نه اینکه مقدار فیلد Digit در حافظه ی متغییر _myVariable را تغییر بده .
استک نخ دیگه چیه؟
بلکه در این حالت (که نام فیلد فراخونی میشه) ، مستقیما به حافظه ی همون فیلد مراجعه میشه (اولین شکل در تصویر بالا که حافظه ی فیلد _myVariable هست) و دیگه کپی شدن (صِرفِ خوندنِ اون فیلد) ، معنا نداره .
بله.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کلاس tuple اینه :
که static ئه و طبعا شیء ای نمیتونه از کلاس static ایجاد بشه. و در ضمن کلاس ها reference type هستند، طبعا وقتی در توضیح tuple ها ذکر شده که value type هستند و توضیح دادم که دلیل اون خطا چیه، دیگه چه کلاسی؟



کدوم کلاس؟ چرا اصلا باید کلاسی باشه یا نباشه؟ چرا میگید "الان یعنی"؟ در پست قبلی اصلا حرفی در مورد کلاس نزدم که موضوع کلاس بودن و نبودن باشه.

سلامی مجدد
خیلی ممنون استاد .
پس کلاس Tuple ، هم استاتیک هست و هم value type هه . حالا چجوری هه که این ، برخلاف همه ی کلاس های دیگه که reference type هستن ، از یه کلاس ، value type ایجاد میکنن؟
استاد ، بعضی وقت ها ، اصطلاح mutable value type میگن ، این ، چه نوع value type هست؟

در مورد ماهیت get و set در مشخصه ها توضیح تون درسته اما من هیچ صحبتی از حافظه و نخ ای نکردم.
استک نخ مورد نظرشون نمیدونم چیه، اگه در مورد زبان سی شارپ حرف می زنید، استک نخ و حافظه اشغالی متد ها و ... از این حرف ها رو بریزید دور، وجود خارجی نداره. اگر هم میخواهید کارکرد CLR یا CoreCLR نسخه فلان رو تحلیل کنید، باید بروید سراغ مهندسی معکوس اش که نمیدونم اصلا به چه دردی میخوره، از نظر من دانستن این چیزها برای برنامه نویس دات نت بیخود ئه. مثل اینه که بخواهید بدونید در بین تریلیون ها سلول داخل بدن تون هر کدوم الان داره چیکار میکنه.

اشاره گر به حافظه چی؟ کدوم اشاره گر؟ کدوم حافظه؟ چی میگید؟ در کدوم پست من دیدید از این حرف ها بزنم؟

استک نخ دیگه چیه؟

استاد ، درباره ی حافظه ی پشته ی نخ ، خودتون توضیح داده بودید :


پست 1527 (پست در لینک بالا) در 3 نقل قولِ آخری تا توضیحات آخرتون .
همچنین در پست 1579 .
و همچنین صفحه 80 .

البته گفته بودین که مدیریت حافظه اش ربطی به gc نداره و به متد و اینها هم ربطی نداره که فراموش کرده بودم .

هر چند در مورد حافظه ی متدها چندان تحقیق نکردم ولی به نظر میرسه که زمانی که هر متد اجرا میشه ، باید حافظه ای براش در نظر گرفته بشه که هم مقادیر پارامترهای ورودی اش را جایی ذخیره کنه و هم اینکه اگه خروجی ای داره ، توی اون حافظه ذخیره بشه و متغییرهای محلی اش هم همینطور .
یکی دیگه اش هم اینه که اون متد وقتی بصورت بازگشتی اجرا بشه ، مقادیر متفاوت ، مربوط به متد مورد نظر ، ذخیره بشه .
درست میگم استاد؟ یعنی هر متد که اجرا میشه ، حداقل برای ذخیره ی این اطلاعاتش ، نیاز به حافظه و بافر داره .
اگه آره ، اطلاعات بیشتری اگه در این رابطه دارین ، ممنون میشم بگین .
اگه نه ، پس این اطلاعات را چجوری و کجا ذخیره میکنه؟

هر چند مقدارِ موقعیتِ اینکه اجرای نخ جاری در پردازنده ، کجا متوقف میشه ، در حافظه ی استکِ نخ ذخیره بشه (درسته دیگه؟) تا پردازنده در اجرای بعدی ، از اون موقعیت به بعد ، ادامه اش را اجرا کنه و ربطی به حافظه ی متد نداشته باشه .


نمیدونم حافظه ها ساختار رو بر مبنای چه معیاری محاسبه می کنید اما من نه همچین حرف هایی زدم و نه در مورد میزان حافظه مصرفی یک ساختار داده مدیریت شده توضیحی دادم. باز زدید تو جاده خاکی. حرف های از اینجور مواردی است :

استراکچرهای managed را نمیدونم ولی یادم میاد قبلا گفته بودید که اندازه ی استراکچر ، به اندازه ی فیلدهای اون هست (نمیدونم منظورتون استراکچرِ managed بود یا unmanaged) .
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد .
پس کلاس Tuple ، هم استاتیک هست و هم value type هه . حالا چجوری هه که این ، برخلاف همه ی کلاس های دیگه که reference type هستن ، از یه کلاس ، value type ایجاد میکنن؟
کلاس Tuple استاتیک ئه و value type هم طبعا نیست، شی ای هم که ازش ساخته نمیشه که بخواهید value type باشه. اشیاء Tuple که از روی کلاس static ایجاد نمیشن. عرض کردم، ساختار داده اشیاء Tuple از نوع value type ئه. برگردید به پست قبلی من و اون لینک سوم که عنوانش ValueTuple Struct (System) بود رو ببینید. حتی می توانید یک شیء Tuple بسازید و در اجرا مقدار ()GetType().ToString. اش رو بررسی کنید.
همونطور که در توضیحات اون کلاس static نوشته بود (لینک اول)، متد های static ای که برای ایجاد Tuple استفاده می شوند رو ارائه می کنه، نه نوع داده خود اشیاء Tuple.
استاد ، بعضی وقت ها ، اصطلاح mutable value type میگن ، این ، چه نوع value type هست؟
ویژگی های متفاوتی هستند، یعنی mutable یا immutable بودن رو مستقل از اون value type یا reference type بودن در نظر بگیرید، مفاهیم مستقل ای هستند. فرض کنید که مقدار یک متغیری x ئه که در جایی از حافظه قرار داره، حالا اگر مقدار اون متغیر رو به مقدار متفاوت y تغییر بدهید دو حالت پیش میاد، یا y روی همون حافظه ای که x بود ذخیره میشه (mutable) یا در موقعیت حافظه متفاوتی ذخیره میشه (immutable)
یعنی اگر نوع داده ای mutable باشه، مقدار داخل اون حافظه قابل تغییر ئه، میتونه ویرایش بشه. ولی در immutable ها مقدار قبلی دیگه قابل ویرایش نیست، مقدار جدید در حافظه متفاوتی قرار میگیره.
فرضا برای نوع داده string نوشته شده :
String objects are immutable: they cannot be changed after they have been created.
یعنی وقتی مقدار یک string رو تغییر می دهید مقدار در حافظه قبلی ویرایش نمیشه، اون همونطور دست نخورده می مونه. بلکه به آدرس حافظه متفاوتی اشاره می کنه که مقدار جدید در اون قرار داره.
طبعا ;int i = 4 ویژگی mutable داره، چون وقتی مقدار 4 رو به 5 تغییر می دهید مقدار در همون آدرس حافظه تغییر می کنه.
استاد ، درباره ی حافظه ی پشته ی نخ ، خودتون توضیح داده بودید :


پست 1527 (پست در لینک بالا) در 3 نقل قولِ آخری تا توضیحات آخرتون .
همچنین در پست 1579 .
و همچنین صفحه 80 .
اونجا گفتم هر نخ ای در پردازنده فیزیکی یا مجازی ای یک پشته داره و مدیریت اش هم ارتباطی با GC نداره. اتفاقا همونجا هم گفتم که حرف هایی می زنید که ارتباطی با GC و #C و حافظه مدیریت شده نداره. "داریم مقدارِ مورد نظر را در حافظه ی اون متدمون که در استکِ نخ مون در نظر گرفته شده بود ، ذخیره میکنیم" از کدوم صحبت من اومده؟ استک نخ مون کدوم نخ ئه؟ این حرف ها از کجا میاد؟
البته گفته بودین که مدیریت حافظه اش ربطی به gc نداره و به متد و اینها هم ربطی نداره که فراموش کرده بودم .
فقط جستجو کنید و ببینید چند بار گفتم اون بحث کذایی stack در #C که نمیدونم از کجا رفته تو ذهن تون رو ول کنید و نکردید.
یک کلاس Stack و <Stack <T هست که در حافظه مدیریت شده NET. براتون پشته میسازه و تمام، فقط همینه.
هر چند در مورد حافظه ی متدها چندان تحقیق نکردم ولی به نظر میرسه که زمانی که هر متد اجرا میشه ، باید حافظه ای براش در نظر گرفته بشه که هم مقادیر پارامترهای ورودی اش را جایی ذخیره کنه و هم اینکه اگه خروجی ای داره ، توی اون حافظه ذخیره بشه و متغییرهای محلی اش هم همینطور .
یکی دیگه اش هم اینه که اون متد وقتی بصورت بازگشتی اجرا بشه ، مقادیر متفاوت ، مربوط به متد مورد نظر ، ذخیره بشه .
درست میگم استاد؟ یعنی هر متد که اجرا میشه ، حداقل برای ذخیره ی این اطلاعاتش ، نیاز به حافظه و بافر داره .
اگه آره ، اطلاعات بیشتری اگه در این رابطه دارین ، ممنون میشم بگین .
بحث مفصلی هست به عنوان Calling Convention که طراح هر معماری مشخص می کنه که فرضا موقع فراخوانی یک متد که فلان تعداد پارامتر و مقدار بازگشتی داره به چه روشی مقادیر پارامتر ها یا مقدار بازگشتی مشخص بشوند. مشخصات پردازنده، کامپایلر و معماری زبان برنامه نویسی و ... باعث شده روش های مختلفی بوجود بیاد. انواع مختلف روش ها برایش هست، یکی دو تا نیست. هر کدوم هم برای یکسری معماری خاص معنی داره. فرضا در پردازنده ای که رجیستر های فلان رو نداره، روشی که از اون رجیستر ها استفاده می کنه کاربردی نداره. برخی زبان های سطح پایین مثل ++C بیش از یک روش رو می شناسند و بکار می برند. اما این یک موضوع سطح پایین ئه (low-level) و در کل مربوط به معماری ماشین (مجازی یا فیزیکی) و دانستن اش برای زبان های سطح بالا مثل #C کاربردی نداره.
هر چند مقدارِ موقعیتِ اینکه اجرای نخ جاری در پردازنده ، کجا متوقف میشه ، در حافظه ی استکِ نخ ذخیره بشه (درسته دیگه؟) تا پردازنده در اجرای بعدی ، از اون موقعیت به بعد ، ادامه اش را اجرا کنه و ربطی به حافظه ی متد نداشته باشه .
کدوم حافظه متد؟ این حرف ها از کجا میاد؟ نه. قبلا چند بار اشاره کردم، متد شما جزئی از مفاهیم زبان سطح بالای #C شما است، پردازنده این چیزها رو درک نمی کنه. پردازنده فقط فرمان هایی که به زبان ماشین بهش دادن پشت سر هم اجرا می کنه، خودش هم تصمیم نمی گیره که کجا رو اجرا کنه یا چه مقداری رو از کجا برداره و باهاش چیکار کنه.
استراکچرهای managed را نمیدونم ولی یادم میاد قبلا گفته بودید که اندازه ی استراکچر ، به اندازه ی فیلدهای اون هست (نمیدونم منظورتون استراکچرِ managed بود یا unmanaged) .
من یادمه، میخواستید بخاطر اتوپلی با DLL با حافظه مدیریت نشده ارتباط برقرار کنید و اندازه حافظه لازم برای ذخیره سازی ساختار های ++C/C در حافظه مدیریت نشده که فرضا در API ویندوز توصیف شده بود رو بر اساس تعداد فیلد ها و نوع داده فیلد های ساختار محاسبه می کردید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد استاد .
خیلی ممنون از توضیح مفصل تون .

استاد ، از اونجایی که لپتاپ گرفتم و یه پروژه را فرضا یه مقداری اش را روی سیستم pc انجام میدم ، و بعد (وقتی که بعد از اون ، با لپتاپ کار میکنم) میخوام ادامه ی اون را در لپتاپ انجام بدم ، و باز مجددا ادامه اش را در سیستم pc انجام بدم و به همین طور این قضیه ادامه داره (یعنی ادامه ی آخرین اصلاحاتی که روی پروژه در لپتاپ یا pc انجام شد را در یکی دیگه انجام بدم و تکمیل کنم) .

بهترین راهکار برای این قضیه ، چیه؟
فرضا اینه که از قضیه و راهکارهایی که github در ویژال استودیو ارائه داده استفاده کنم (البته هنوز از github استفاده نکردم . اما اگه اشتباه نکنم ، برای همین قضیه طراحی شده . درست میگم؟) .

یا اینکه توی فلش بریزم و به لپتاپ و pc انتقال بدم؟
یا راهکار دیگه ای هم وجود داره؟

تشکر استاد
 

the_king

مدیرکل انجمن
سلامی مجدد استاد .
خیلی ممنون از توضیح مفصل تون .

استاد ، از اونجایی که لپتاپ گرفتم و یه پروژه را فرضا یه مقداری اش را روی سیستم pc انجام میدم ، و بعد (وقتی که بعد از اون ، با لپتاپ کار میکنم) میخوام ادامه ی اون را در لپتاپ انجام بدم ، و باز مجددا ادامه اش را در سیستم pc انجام بدم و به همین طور این قضیه ادامه داره (یعنی ادامه ی آخرین اصلاحاتی که روی پروژه در لپتاپ یا pc انجام شد را در یکی دیگه انجام بدم و تکمیل کنم) .

بهترین راهکار برای این قضیه ، چیه؟
بهترین راهکار برای هر کسی متفاوته، بهترینی وجود نداره که من برای شما مشخص کنم. می توانید پروژه رو روی یک فلش درایو یا هارد دیسک قابل حمل جابجا کنید یا از GitHub یا Azure DevOps و ... استفاده کنید. در هر صورت باید بصورت دوره ای در جای دیگری نسخه بروز شده پروژه رو نگهدارید.

Top 10 GitHub Alternatives That You Can Consider
فرضا اینه که از قضیه و راهکارهایی که github در ویژال استودیو ارائه داده استفاده کنم (البته هنوز از github استفاده نکردم . اما اگه اشتباه نکنم ، برای همین قضیه طراحی شده . درست میگم؟) .
بله.
 

جدیدترین ارسال ها

بالا