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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اینکه حافظه جدیدی تخصیص داده بشه یا نشه به نحوه پیاده سازی زبان و بخش عملگر انتساب ( = ) مربوطه، ربطی به new که یک کلمه کلیدی زبان ئه نداره.
توضیحات عملگر new رو بخونید، ببینید داخلش صحبتی در مورد حافظه جدید شده یا نه. اگر نشده پس ربطی به حافظه جدید نداره.
فرض کنید که i = 4 + 5 رو دارید، 5 در یک حافظه مجزا است، 4 در یک حافظه مجزا، 4 + 5 در یک حافظه دیگه محاسبه میشه و عملگر = این مقدار رو در حافظه i کپی می کنه. حالا اینکه در سمت راست = ئه new ای بوده یا نبوده و چه تعدادی حافظه مجزا بوده که ربطی به عملکرد عملگر انتساب و کاری که با مقدار i و حافظه اش می کنه نداره.

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


و اینکه استاد ، در .net core ، الان خیلی از کتابخونه هایی که در دات نت فریم وورک هست ، در اونجا هم هست . مثلا ComboBox ئه wpf ، در دات نت کور 3 هم هست . این به این معنا هست که در سیستم عامل های دیگه (مثل اندروید یا مکینتاش) هم میتونیم از این کتابخونه های دات نت کور (مثل همین کمبوباکس) استفاده کنیم؟
یا اینکه مثل قضیه ی استفاده از کتابخونه های رجیستری در دات نت کور هست که قبلا درباره ی دات نت کور گفتید (که چون رجیستری ، فقط در ویندوز وجود داره ، پس با استفاده از این کتابخونه ، اون برنامه ای که از دات نت کور استفاده میکنه ، دیگه با سیستم عامل های دیگه ، سازگار نیست) .

Kernel32.dll توابع هسته سیستم عامل نیست، شامل یکسری توابع اساسی است که برنامه های سطح کاربری ویندوز ازش استفاده می کنند.
و در کل برنامه ای در سطح کاربر نمی تونه از هسته سیستم عامل سرویسی بگیره که نیاز به دسترسی سطح هسته داره.

این توابع و هدرهایی که نام میبره ، مربوط به هسته ی سیستم عامل ویندوز هستن . درسته؟ :



سرویس هایی که شما بخواهید در سطح کاربری دریافت کنید به همون شکل هم نقض شدنی هستند :

آها . یعنی یه برنامه یا یه شخصی با دسترسی admin هم میتونه کاری کنه که این دسترسِ برنامه مون به درایوری که کتابخونه یا سرویس اش که توسط برنامه نویس ++C انجام شد و ما در برنامه ی سی شارپ مون در سطح دسترسی admin ، بهش دسترسی داریم را منع کنه؟
البته باز هم این اش برای بعضی از برنامه هام ، شاید مهم نباشه .

منطق استدلال تون رو متوجه نشدم ولی در چه موضوعی تردید دارید؟ در اینکه ++C برای نوشتن نرم افزار سطح هسته و ارتباط سطح پایین با سخت افزار قابل استفاده است؟ یا اینکه #C این توانایی ها رو نداره؟ اگر از زبان ++C شناخت کافی نداشته باشید که جایی برای بحث و گفتگو نیست.

بله.


خیر.


از نظر فنی #C نمیتونه همچین کاری رو انجام بده. می توانید واسط کاربری برنامه رو با #C طراحی کنید اما بدون استفاده از یک سرویس سیستمی که خودش به زبان #C قابل پیاده سازی نیست کار نخواهد کرد.

اینکه سی شارپ چرا این توانایی را نداره؟
غیر از اینه که برنامه نویس های ++C ، وقتی میخوان درایور بسازن ، از هِدِر ها و فایل ها و کتابخونه هایی که هسته ی سیستم عامل ویندوز (در اون لینک بالا) که در اختیارشون میذاره استفاده و فراخونی میکنن و در واقع متدهای پایه را خودشون از اول نمینویسن؟
اگه آره ، خوب سی شارپ هم قابلییت فراخونی خیلی از متدها و کلا اعضایی که ++C قابلیت فراخونی شونو داره ، داره دیگه .
پس چرا با سی شارپ نمیشه برنامه ی سطح درایور ساخت؟
یا اینکه میشه اما قابلیت های سی شارپ (مثلا بخاطر اینکه توانایی این رو نداره که بعضی از اعضایی که ++C میتونه فراخونی شون کنه ، اون سی شارپ نمیتونه) ، در ساخت درایور ، کمتره؟

همچنین تشکر از بقیه ی جواب هاتون :rose:
 

the_king

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

یا کار سیستم عامل بود؟
هر دو. حافظه ای که سیستم عامل در اختیار داره با حافظه ای که در ماشین مجازی هست و حافظه ای که داخل برنامه NET. هست در لایه های متفاوتی قرار دارند.

اما از دید پروسه ، این تغییر آدرس ، پنهان میموند و پروسه ، یه آدرس نسبی ، نسبت به page هایی که براش در نظر گرفته شده بود را داره و بنابراین این تغییر آدرس را متوجه نمیشه . درسته؟
جابجایی آدرس حافظه فیزیکی توسط سیستم عامل رو که ابدا متوجه نمیشه.
و مادامی که برنامه با آدرس های مدیریت شده داخل NET. سر و کار داره، بله. برای کد NET. جابجا شدن شیء a، مادامی که برای ارجاع به شیء از همون a و آدرس مدیریت شده استفاده میشه اهمیتی نداره، متوجه جابجایی اش نمیشه. احتمال بروز مشکل زمانی است که بخواد این آدرس حافظه مدیریت شده رو به آدرس حافظه نسبی RAM تبدیل کنه، بخواد بجای آدرس حافظه مدیریت شده، آدرس حافظه فیزیکی رو بکار ببره. ممکنه لحظه ای بعد اون آدرس قبلی تغییر کنه و نامعتبر بشه. اینجا است که باید شیء با پونز در جای خودش ثابت بشه تا توسط GC جابجا نشه.

و اینکه استاد ، در .net core ، الان خیلی از کتابخونه هایی که در دات نت فریم وورک هست ، در اونجا هم هست . مثلا ComboBox ئه wpf ، در دات نت کور 3 هم هست . این به این معنا هست که در سیستم عامل های دیگه (مثل اندروید یا مکینتاش) هم میتونیم از این کتابخونه های دات نت کور (مثل همین کمبوباکس) استفاده کنیم؟
فعلا WPF اختصاصی ویندوز ئه، و بعید میدونم خود مایکروسافت روی پلتفرم دیگری توسعه اش بده، اما WPF کد باز داره، ممکنه روزی همچین اتفاقی بیافته.

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

این توابع و هدرهایی که نام میبره ، مربوط به هسته ی سیستم عامل ویندوز هستن . درسته؟ :

بله.

آها . یعنی یه برنامه یا یه شخصی با دسترسی admin هم میتونه کاری کنه که این دسترسِ برنامه مون به درایوری که کتابخونه یا سرویس اش که توسط برنامه نویس ++C انجام شد و ما در برنامه ی سی شارپ مون در سطح دسترسی admin ، بهش دسترسی داریم را منع کنه؟
البته باز هم این اش برای بعضی از برنامه هام ، شاید مهم نباشه .
از نظر فنی امکانش هست. اما خیلی فرق می کنه که دارید از یک سرویس عمومی و ابتدایی مثل قفل کردن فایل استفاده می کنید یا از یک درایور گمنام و اختصاصی که تشخیص نحوه کارش برای سایر برنامه ها دشوار ئه.

اینکه سی شارپ چرا این توانایی را نداره؟
غیر از اینه که برنامه نویس های ++C ، وقتی میخوان درایور بسازن ، از هِدِر ها و فایل ها و کتابخونه هایی که هسته ی سیستم عامل ویندوز (در اون لینک بالا) که در اختیارشون میذاره استفاده و فراخونی میکنن و در واقع متدهای پایه را خودشون از اول نمینویسن؟
اگه آره ، خوب سی شارپ هم قابلییت فراخونی خیلی از متدها و کلا اعضایی که ++C قابلیت فراخونی شونو داره ، داره دیگه .
پس چرا با سی شارپ نمیشه برنامه ی سطح درایور ساخت؟
یا اینکه میشه اما قابلیت های سی شارپ (مثلا بخاطر اینکه توانایی این رو نداره که بعضی از اعضایی که ++C میتونه فراخونی شون کنه ، اون سی شارپ نمیتونه) ، در ساخت درایور ، کمتره؟
کد #C در ماشین مجازی NET. اجرا میشه، به عنوان یک برنامه سطح کاربر. دسترسی اش هم در سطح یک برنامه کاربری است. مثل هر برنامه عادی دیگری به سرویس های سطح هسته سیستم عامل دسترسی نداره. مثل اینه که بخواهید در خیابان متد باز کردن در کشوی داخل اتاقی رو فراخوانی کنید، حق ورود به داخل خانه و اتاق رو ندارید، هیچگاه داخل اتاق نخواهید شد که به کشوی کمد دسترسی داشته باشید. اگر غیر از این بود که هر ویروسی هر کاری دلش میخواست می کرد و ویروس کش هم جلویش را نمی توانست بگیرد.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد .
کد زیر را در کلاس usercontrol1 برای wpf ، نوشتم (پروژه از نوع user control library هست) :

C#:
        public static int CreateComboBox(int hwndParent, int x, int y, int width, int height)
        {
            UserControl1 myUserControl = new UserControl1();
            myUserControl.HorizontalAlignment = HorizontalAlignment.Left;
            myUserControl.VerticalAlignment = VerticalAlignment.Top;
            myUserControl.Margin = new Thickness(x, y, 0, 0);
            myUserControl.Width = width;
            myUserControl.Height = height;

            HwndSource hwndChildSource = HwndSource.FromVisual(myUserControl) as HwndSource;
            return 0;
        }

چون برای خروجی اتوپلی میخوام ، مجبورم اول هندل usercontrol1 ام را بگیرم اما وقتی به خط آخر ، یعنی به متد HwndSource.FromVisual میرسه ، خروجی اش که hwndChildSource باشه ، null هه .
بخاطر چیه؟
بخاطر اینه که UserControl1 مون را به والد ای اضافه نکردیم؟
و کلا قبل از اینکه UserControl1 مون را به والدی اضافه کنیم ، بخوایم handle اش را بدست بیاریم ، چی کار باید کنیم؟
کد زیر را هم میزنم ، بازم null میده :

PresentationSource source = HwndSource.FromVisual(myUserControl);

تشکر
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
کد زیر را در کلاس usercontrol1 برای wpf ، نوشتم (پروژه از نوع user control library هست) :

C#:
        public static int CreateComboBox(int hwndParent, int x, int y, int width, int height)
        {
            UserControl1 myUserControl = new UserControl1();
            myUserControl.HorizontalAlignment = HorizontalAlignment.Left;
            myUserControl.VerticalAlignment = VerticalAlignment.Top;
            myUserControl.Margin = new Thickness(x, y, 0, 0);
            myUserControl.Width = width;
            myUserControl.Height = height;

            HwndSource hwndChildSource = HwndSource.FromVisual(myUserControl) as HwndSource;
            return 0;
        }

چون برای خروجی اتوپلی میخوام ، مجبورم اول هندل usercontrol1 ام را بگیرم اما وقتی به خط آخر ، یعنی به متد HwndSource.FromVisual میرسه ، خروجی اش که hwndChildSource باشه ، null هه .
بخاطر چیه؟
بخاطر اینه که UserControl1 مون را به والد ای اضافه نکردیم؟
و کلا قبل از اینکه UserControl1 مون را به والدی اضافه کنیم ، بخوایم handle اش را بدست بیاریم ، چی کار باید کنیم؟
کد زیر را هم میزنم ، بازم null میده :

PresentationSource source = HwndSource.FromVisual(myUserControl);

تشکر
شیء ای که ساخته اید رندر نشده، handle هم متعلق به اون کنترل نیست، متعلق به HwndSource ئه.
اگر بخواهید برای کنترل از HwndSource استفاده کنید باید HwndSource.FromVisual رو در رخداد Loaded اون کنترل اجرا کنید، زمانی که کنترل رندر شده.
UserControl1 که خودش پنجره و Handle نداره.
بجای اینکه از HwndSource استفاده کنید می توانید System.Windows.Forms.Integration.ElementHost ای بسازید که اون myUserControl فرزندش باشه و ElementHost.Handle رو بکار ببرید. به WindowsFormsIntegration و System.Windows.Forms رفرنس می دهید.

در ضمن Handle اصولا نباید int باشه، حتی اگر قراره همیشه 32 بیتی کامپایل و اجرا بشه. اصولا همه Handle ها باید IntPtr باشه.
حالا اگر میخواهید موقع بازگرداندن مقدار از ToInt32 برای IntPtr استفاده کنید تا int بشه مانعی نداره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شیء ای که ساخته اید رندر نشده، handle هم متعلق به اون کنترل نیست، متعلق به HwndSource ئه.
اگر بخواهید برای کنترل از HwndSource استفاده کنید باید HwndSource.FromVisual رو در رخداد Loaded اون کنترل اجرا کنید، زمانی که کنترل رندر شده.
UserControl1 که خودش پنجره و Handle نداره.
بجای اینکه از HwndSource استفاده کنید می توانید System.Windows.Forms.Integration.ElementHost ای بسازید که اون myUserControl فرزندش باشه و ElementHost.Handle رو بکار ببرید. به WindowsFormsIntegration و System.Windows.Forms رفرنس می دهید.

در ضمن Handle اصولا نباید int باشه، حتی اگر قراره همیشه 32 بیتی کامپایل و اجرا بشه. اصولا همه Handle ها باید IntPtr باشه.
حالا اگر میخواهید موقع بازگرداندن مقدار از ToInt32 برای IntPtr استفاده کنید تا int بشه مانعی نداره.

خیلی ممنون استاد .
پس چرا وقتی این کار را با کنترل های winform میکنیم ، مشکلی نداره؟
یعنی توی winform ، وقتی یه کنترلی را ساختیم (و به والدی اضافه نکرده باشیم) ، میتونیم handle اش را بگیریم و بعد با متد SetParent (در win api) ، والدش را مشخص کنیم اما در wpf چرا تا والدش مشخص نشه (و بنابراین رندر نمیشه) ، نمیشه handle اش را گرفت؟

بجز قضیه ی ElementHost ، راه مستقیم دیگه ای نداره؟
تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
پس چرا وقتی این کار را با کنترل های winform میکنیم ، مشکلی نداره؟
ربطی بهم ندارن، دو تا پلتفرم کاملا متفاوت ئه با معماری های متفاوت. Handle متعلق به پنجره های Windows Forms ئه، المنت های WPF کنترل ویندوز نیستند که پنجره ویندوز لازم داشته باشن، پنجره ندارن. صرفا وجود یک پنجره ضروری است که اونم برای قرار گرفتن المنت Window نمیشد نباشه.

یعنی توی winform ، وقتی یه کنترلی را ساختیم (و به والدی اضافه نکرده باشیم) ، میتونیم handle اش را بگیریم و بعد با متد SetParent (در win api) ، والدش را مشخص کنیم اما در wpf چرا تا والدش مشخص نشه (و بنابراین رندر نمیشه) ، نمیشه handle اش را گرفت؟
یادتون نره، قبلا گفتم، کنترل ساختن ربطی به پنجره ساختن نداره، قبلا در مورد اینکه کنترل شیء انتزاعی است صحبت کرده بودیم. پنجره ویندوز ممکنه در یک کنترل موقع ساختن شیء از کلاس اش ساخته بشه، یا صرفا موقع نمایش اش یا بعدا موقعی که نیاز به عملیات خاصی مثل Focus داره یا هیچوقت. اینکه کنترل بسازید به این معنی نیست که حتما پنجره ای هم ساخته شده.
در WPF کنترل پنجره نداره، اساس Windowless ئه، فاقد پنجره. که پنجره داشتنش نه ربطی به والد داشتن داره و نه به رندر شدن. Handle گرفتن از کنترل WPF بی معنیه.

بجز قضیه ی ElementHost ، راه مستقیم دیگه ای نداره؟
چه مستقیمی؟ پلتفرم کاملا متفاوتی دارن، ارتباطی مستقیمی بین کنترل WPF و پنجره های ویندوز نیست که راه مستقیمی باشه.
Handle پنجره Windows Forms در کنترل WPF که بر اساس پنجره طراحی نشده نقشی نداره.
صرفا برای نمایش رندر WPF در ویندوز نیاز به یک پنجره پایه هست که بستر رندر باشه، مثل اون پنجره ای که برای المنت Window بکار میره یا ElementHost که باید روی پنجره ویندوز دیگری قرار بگیره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ربطی بهم ندارن، دو تا پلتفرم کاملا متفاوت ئه با معماری های متفاوت. Handle متعلق به پنجره های Windows Forms ئه، المنت های WPF کنترل ویندوز نیستند که پنجره ویندوز لازم داشته باشن، پنجره ندارن. صرفا وجود یک پنجره ضروری است که اونم برای قرار گرفتن المنت Window نمیشد نباشه.


یادتون نره، قبلا گفتم، کنترل ساختن ربطی به پنجره ساختن نداره، قبلا در مورد اینکه کنترل شیء انتزاعی است صحبت کرده بودیم. پنجره ویندوز ممکنه در یک کنترل موقع ساختن شیء از کلاس اش ساخته بشه، یا صرفا موقع نمایش اش یا بعدا موقعی که نیاز به عملیات خاصی مثل Focus داره یا هیچوقت. اینکه کنترل بسازید به این معنی نیست که حتما پنجره ای هم ساخته شده.
در WPF کنترل پنجره نداره، اساس Windowless ئه، فاقد پنجره. که پنجره داشتنش نه ربطی به والد داشتن داره و نه به رندر شدن. Handle گرفتن از کنترل WPF بی معنیه.


چه مستقیمی؟ پلتفرم کاملا متفاوتی دارن، ارتباطی مستقیمی بین کنترل WPF و پنجره های ویندوز نیست که راه مستقیمی باشه.
Handle پنجره Windows Forms در کنترل WPF که بر اساس پنجره طراحی نشده نقشی نداره.
صرفا برای نمایش رندر WPF در ویندوز نیاز به یک پنجره پایه هست که بستر رندر باشه، مثل اون پنجره ای که برای المنت Window بکار میره یا ElementHost که باید روی پنجره ویندوز دیگری قرار بگیره.

خیلی ممنون استاد .
استاد ، الان منظورتون اینه که کلا کنترل های wpf ، هندل ندارن؟
یا من خوب متوجه نشدم؟
چون یه پروژه که ساختم و توش یه کمبوباکس گذاشتم و با کد زیر :

C#:
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(this.myComboBox);

هندل اون myComboBox را بهم داد (شیِ hwndSource ، نال نیست و handle اش هم مقدار داره) . کد بالا ، در رویداد کلیک دکمه ای هست .
تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
استاد ، الان منظورتون اینه که کلا کنترل های wpf ، هندل ندارن؟
خیر، Window Handle ندارن، Windowless هستند. وقتی پنجره ای در کار نباشه Handle پنجره ای هم در کار نیست.

یا من خوب متوجه نشدم؟
چون یه پروژه که ساختم و توش یه کمبوباکس گذاشتم و با کد زیر :

C#:
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(this.myComboBox);

هندل اون myComboBox را بهم داد (شیِ hwndSource ، نال نیست و handle اش هم مقدار داره) . کد بالا ، در رویداد کلیک دکمه ای هست .
تشکر استاد .
این Handle اون myComboBox نیست، myComboBox پنجره نداره که Handle داشته باشه. این مقداری که دریافت می کنید Handle اون پنجره ای است که HwndSource ساخته. در پست #1,604 که گفتم متعلق به HwndSource ئه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیر، Window Handle ندارن، Windowless هستند. وقتی پنجره ای در کار نباشه Handle پنجره ای هم در کار نیست.


این Handle اون myComboBox نیست، myComboBox پنجره نداره که Handle داشته باشه. این مقداری که دریافت می کنید Handle اون پنجره ای است که HwndSource ساخته. در پست #1,604 که گفتم متعلق به HwndSource ئه.

خیلی ممنون استاد .
ولی من دقیق اون تیکه ای که بولد کردم را متوجه نشدم .
چه پنجره ای را HwndSource ساخته؟

اون myComboBox ، یه شی از UserControl هست که در Content اش ( ئه UserControl اش) ، یه ComboBox هست . و این myComboBox را به Window (ئه wpf) اضافه کردم .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
ولی من دقیق اون تیکه ای که بولد کردم را متوجه نشدم .
چه پنجره ای را HwndSource ساخته؟
عنوان کلاس HwndSource چیه؟ "Presents Windows Presentation Foundation (WPF) content in a Win32 window"
یعنی محتویات WPF رو در یک پنجره ویندوز قرار میده، از HwndSource پنجره میخواهید، اونم پنجره میسازه دیگه. توضیحات HwndSource رو در سایت مایکروسافت ببینید. با تابع CreateWindowEx ویندوز پنجره ساخته میشه. HwndSource هم از این تابع استفاده می کنه.
 

SU-57

Active Member
سلام

این کد رو در نظر بگیرید

کد:
private void button1_Click(object sender, EventArgs e)
{

    BigInteger f = Bigfactorial(30);
    MessageBox.Show(f.ToString());

}

public static BigInteger Bigfactorial(int n)
{
    if (n == 1)
    {
        return new BigInteger(1);
    }
    else
    {
        BigInteger temp = BigInteger.Multiply(Bigfactorial(n - 1), new BigInteger(n));
        return temp;
    }
}


1- در یک سایت اینترنتی نوشته کلاس BigInteger ولی در سایت مایکروسافت نوشته struct ئه. بالاخره BigInteger یک کلاسه یا struct.

حالا که مایکروسافت گفته struct ئه پس چطوری می شه ازش با new شی ساخت چون اینطور که می دونم فقط از کلاس ها می شه شی ساخت.

2- لطفا این کد رو هم توضیح بدید که دقیقا چیکار می کنه منظورم Multiply و اون دو تا کد که با ویرگول جدا شدن

کد:
BigInteger.Multiply(Bigfactorial(n - 1), new BigInteger(n));

3- بعد من در این قسمت کد کلمات public static رو بر میدارم ولی باز کد درست کار می کنه. چرا برنامه نویس از کلمهstatic در اینجا استفاده کرده وقتی بودن و نیودنش فرقی نداره

کد:
public static BigInteger Bigfactorial(int n)


4- در این کد چرا برنامه نویس از return 1; استفاده نکرده و به جاش اینجوری نوشته. آیا فرقی داره در اصل کار

کد:
  if (n == 1)
  {
     return new BigInteger(1);
  }
الان این new یک شی از استراکت BigInteger می سازه و بعد مقدارش رو یک میذاره یعنی همون عددی که توی پرانتز هست
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام

این کد رو در نظر بگیرید

کد:
private void button1_Click(object sender, EventArgs e)
{

    BigInteger f = Bigfactorial(30);
    MessageBox.Show(f.ToString());

}

public static BigInteger Bigfactorial(int n)
{
    if (n == 1)
    {
        return new BigInteger(1);
    }
    else
    {
        BigInteger temp = BigInteger.Multiply(Bigfactorial(n - 1), new BigInteger(n));
        return temp;
    }
}


1- در یک سایت اینترنتی نوشته کلاس BigInteger ولی در سایت مایکروسافت نوشته struct ئه. بالاخره BigInteger یک کلاسه یا struct.

حالا که مایکروسافت گفته struct ئه پس چطوری می شه ازش با new شی ساخت چون اینطور که می دونم فقط از کلاس ها می شه شی ساخت.

2- لطفا این کد رو هم توضیح بدید که دقیقا چیکار می کنه منظورم Multiply و اون دو تا کد که با ویرگول جدا شدن

کد:
BigInteger.Multiply(Bigfactorial(n - 1), new BigInteger(n));

3- بعد من در این قسمت کد کلمات public static رو بر میدارم ولی باز کد درست کار می کنه. چرا برنامه نویس از کلمهstatic در اینجا استفاده کرده وقتی بودن و نیودنش فرقی نداره

کد:
public static BigInteger Bigfactorial(int n)


4- در این کد چرا برنامه نویس از return 1; استفاده نکرده و به جاش اینجوری نوشته. آیا فرقی داره در اصل کار

کد:
  if (n == 1)
  {
     return new BigInteger(1);
  }

سلام . البته اگه جایی مشکلی داره ، استاد تصحیح کنن .

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

2) متد BigInteger.Multiply که دو تا ورودی میگیره و اون دو تا را در هم ضرب میکنه .
اونهایی که با ویرگول جدا شدن ، آرگومانن که به متد ، پاس داده میشن .

آرگومانِ دوم که new BigInteger(n) هست که مقدارش را از پارامترِ همون متد که n هست میگیره (حالا هر عددی که بود) و همون عدد را در قالبِ شیِ BigInteger ارائه میده .
آرگومانِ اول که Bigfactorial(n - 1) هست هم که یکی از مقدار پارامترِ n کم میکنه و دوباره متد Bigfactorial را بصورت بازگشتی با این مقدار جدید (به عنوان آرگومان) ، فراخونی میکنه (تا خروجیِ نهاییِ این متد بازگشتی ، به 1 برسه) .

3) برای درک این پرسش ، اول باید کلمه ی کلیدیِ static را متوجه شی .
باز قبل از اینکه به کلمه ی کلیدی static رو درک کنی ، بهتره مفهوم شی گرایی را متوجه شی تا قضیه ی static را کامل تر درک کنی .
داستانش مفصل هه اما کلمه ی کلیدی static ، برای وقتی استفاده میشه که اون عضو (متد و ...) ، قرار نباشه که بصورت شی گرا اجرا بشه و وابسته به شی نباشه .

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

4) چون وقتی مینویسید 1 ، بصورت پیش فرض ، شی ای از نوع int32 در نظر گرفته میشه . اما خروجیِ متدِ Bigfactorial تون از نوعِ BigInteger هست . پس نیاز به شی ای از نوع BigInteger داره .
بله ، فرق داره و نمیشه اون جوری نوشت مگر اینکه تبدیل کنید .


الان این new یک شی از استراکت BigInteger می سازه و بعد مقدارش رو یک میذاره یعنی همون عددی که توی پرانتز هست

بله .
 

the_king

مدیرکل انجمن
سلام

این کد رو در نظر بگیرید

کد:
private void button1_Click(object sender, EventArgs e)
{

    BigInteger f = Bigfactorial(30);
    MessageBox.Show(f.ToString());

}

public static BigInteger Bigfactorial(int n)
{
    if (n == 1)
    {
        return new BigInteger(1);
    }
    else
    {
        BigInteger temp = BigInteger.Multiply(Bigfactorial(n - 1), new BigInteger(n));
        return temp;
    }
}


1- در یک سایت اینترنتی نوشته کلاس BigInteger ولی در سایت مایکروسافت نوشته struct ئه. بالاخره BigInteger یک کلاسه یا struct.
نمیدونم اون سایتی که منظورتون هست در مورد چه کلاسی صحبت می کنه، BigInteger ای که در موردش حرف میزده الزاما System.Numerics.BigInteger نیست. ممکنه مربوط به یک کلاس اختصاصی یا یک کتابخانه دیگری باشه و در مورد System.Numerics.BigInteger نمیگه. System.Numerics.BigInteger یک struct ئه.

حالا که مایکروسافت گفته struct ئه پس چطوری می شه ازش با new شی ساخت چون اینطور که می دونم فقط از کلاس ها می شه شی ساخت.
new برای فراخوانی متد سازنده شیء است، متدی که اجراش منجر به ایجاد شی میشه. اما در #C شیء ساختن مختص کلاس ها نیست.
به این دلیل که در زبان هایی که کاملا شیء گرا هستند، مثل #C، همه انواع داده ای شیء محسوب میشن، نوع داده ای نداریم که نوعی object نباشه، مثلا int یا همون Int32 نهایتا یک نوع object ئه و در توضیحات وراثتش (Inheritance) نوشته شده :
به همین جهت new مختص کلاس ها نیست. مثلا :
C#:
int x = new int();

3- بعد من در این قسمت کد کلمات public static رو بر میدارم ولی باز کد درست کار می کنه. چرا برنامه نویس از کلمهstatic در اینجا استفاده کرده وقتی بودن و نیودنش فرقی نداره

کد:
public static BigInteger Bigfactorial(int n)
کد Bigfactorial رو ببینید، یک مقدار ورودی n رو میگیره و بر اساسش یک محاسبه رو انجام میده. برایش اهمیتی نداره که داخل کدوم کلاس نوشته شده، کاری با مقادیر داخل اون کلاس نداره. کارکردش مستقل ئه.
فرض کنیم که این Bigfactorial در کلاس Form1 تعریف شده، شما در داخل کد Form1 می توانید بدون وجود اون static کد رو اجرا کنید و مشکلی نخواهید داشت، چرا؟ چون Bigfactorial در همون کلاسی تعریف شده که دارید ازش استفاده می کنید. اما چرا public تعریف شده؟ هدف داشته. نویسنده اش قصد داره به سایر کلاس ها اجازه بده تا از این Bigfactorial استفاده کنند، فراخوانی اش کنند.
فرض کنیم که می خواستید در کلاس Form2 از Bigfactorial استفاده کنید، فراخوانی اش کنید. وقتی static هست، به سادگی با Form1.Bigfactorial بهش دسترسی دارید :
C#:
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            BigInteger x = Form1.Bigfactorial(5);
        }
    }

اما وقتی static رو حذف می کنید با یک مشکل مواجه می شوید. چون وقتی static نیست، پس متعلق به یک شیء از کلاس Form1 ئه. شما مجبور می شوید که یک شیء از کلاس Form1 بسازید تا بتوانید از BigInteger استفاده کنید :
C#:
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            Form1 f1 = new Form1();
            BigInteger x = f1.Bigfactorial(5);
        }
    }
بخاطر حذف شدن static مجبور شدیم که از Form1 شی بسازیم، شیء ای که ممکنه یک عالمه اجزاء داشته باشه و ما به هیچکدوم نیازی نداشتیم، بیخود و بی جهت و فقط برای فراخوانی Bigfactorial یک مقدار حافظه رو هدر می دهیم و یک مقدار پردازش اضافی انجام می دهیم تا فرم ایجاد بشه.

4- در این کد چرا برنامه نویس از return 1; استفاده نکرده و به جاش اینجوری نوشته. آیا فرقی داره در اصل کار

کد:
  if (n == 1)
  {
     return new BigInteger(1);
  }
نوع داده ای که از Bigfactorial برگردونده میشه BigInteger ئه، چون در تعریفش اینطور مشخص شده. به همین خاطر هر چیزی که از داخلش return کنید تبدیل میشه به BigInteger. اگر قابل تبدیل نباشه خطا میده.
برنامه نویس میدونسته که BigInteger میتونه بصورت خودکار int رو به BigInteger تبدیل کنه :
C#:
BigInteger x = 1;
به همین جهت برنامه نویس حق انتخاب داشته، میتونه بجای BigInteger یک int رو مشخص کنه و بقیه کار رو به سیستم تبدیل خودکار نوع داده بسپاره.
حتی اون return 1 هم موقع برگردوندن تبدیل به BigInteger میشه، int نمیمونه.
در عمل تفاوتی بین دو حالت نیست، هر دو جور کد یک نتیجه داره، نهایتا اون 1 تبدیل میشه به یک BigInteger
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
خیلی ممنون استاد .
BigInteger ، تبدیل ضمنی را پشتیبانی میکرد . چک نکردم :)
راستی استاد ، اندازه ی BigInteger چقدره؟
یعنی حداکثر تا چه عددی توش میشه ریخت . هر چند در سایتش نوشته که حداقل و حداکثر ، انگار نداره اما من دقیق متوجه نشدم . بالاخره تا یه جایی باید محدودیت داشته باشه هم اندازه اش و هم بنابراین مقدار عددی که قبول میکنه.
من sizeof را براش زدم اما ارور میداد .
راستی استاد کدهای جاوا را توی اون تاپیک نوشتید ، کد جاوا ، چقدر شبیه به کد سی شارپ هست! انگار اصلا توی سینتکس ، کوچیکترین فرقی ندارن!
بعد اینکه استاد ، چرا سی شارپ ، عملگری برای محاسبه ی توان (توان در ریاضی) نداره (فقط متد Math.Pow داره) اما لوا که قابلیت های بسیار ضعیفی در ریاضیات داره ، این عملگر را داره!


-----------------------------------------------


و یه چیز بسیار تعجب گرایانه برای من اینه که الان یه لینکی پیدا کردم که میگه یه چیزی بنام .Net Native داریم که همون کارایی زبان C++ Native را در . net framework ئه 4.5.1 و بالاتر (و انگار در ویندوز 10) ، ارائه میکنه . یعنی کدهای دات نت را دیگه به زبان IL و میانی ، کمپایل نمیکنه و مستقیما به کد زبان ماشین تبدیل میکنه :


من این همه خودمو پاره کردم گفتم ای کاش سی شارپ یه طراحی ای میکرد که کارایی اش شبیه C++ Native میبود (مثلا همین زبان میانی را نادیده میگرفت) ، یه چیزی درباره ی این .Net Native میگفتین ها :green:
البته از محدودیت هاش و اینکه چجوری بکار گرفته میشه و اینکه آیا همه ی قابلیت هایی که با .net framework ، در حالت عادی ای که میتونیم انجام بدیم را در اونجا هم میتونیم انجام بدیم یا نه را نمیدونم . فکر کنم مبحث خیلی جالبی باشه برای کسایی که بخوان با سی شارپ ، کارایی ای در حد C++ Native داشته باشن .
ان شاء ا... اگه شد ، در آینده بخونم .

--------------------------------------------

و اینکه استاد ، در پروژه ی پشتیبانگیرم (که از alphavss استفاده میکرد) ، با توجه به این موارد ، شما چه نسخه از دات نت فریم وورک را توصیه میکنید؟
چون میخوام از alphavss v2.0 استفاده کنم ، این نسخه ، با .net framework 4.5 یا بالاتر سازگاره (مگر اینکه پیشنهاد بدید که از نسخه ی قبلی alphavss استفاده کنم) .
همچنین در wpf ، میخوام از قابلیت و کلاسِ WindowChrome هم استفاده کنم که انگار بصورت رسمی ، از نسخه ی .net framework 4.5 اضافه شد .
و از اونجایی که .net Native انگار روی .net framework 4.5.1 و بالاتر میتونه فعال بشه ، برای اینکه شاید در نسخه های بعد ، از این .net native استفاده کنم ، پس حداقل نسخه ی .net framework 4.5.1 را انتخاب کنم ، چطوره؟
تشکر استاد . :rose:
 
آخرین ویرایش:

the_king

مدیرکل انجمن
راستی استاد ، اندازه ی BigInteger چقدره؟
حد بالا و پایین نداره، چون بر اساس آرایه طراحی شده، هر چقدر لازم باشه آرایه بزرگتر میشه. تا جایی که بخاطر کمبود حافظه خطا بده یا از لحاظ تئوری طول آرایه به Int32.MaxValue برسه.

من sizeof را براش زدم اما ارور میداد .
هر چیزی رو که میخواهید استفاده کنید اول توضیحاتش رو بخونید تا ببینید برای چه مواردی قابل استفاده است. sizeof برای همچین ساختاری قابل استفاده نیست.

راستی استاد کدهای جاوا را توی اون تاپیک نوشتید ، کد جاوا ، چقدر شبیه به کد سی شارپ هست! انگار اصلا توی سینتکس ، کوچیکترین فرقی ندارن!
بدون تفاوت که نیستن ولی شبیه هستند بخاطر اینکه جفت شون از ++C الهام گرفته اند. و در ضمن مایکروسافت تمایل داشته که مهاجرت برنامه نویسان سایر زبان ها به #C و پلتفرم خودش کمترین هزینه رو داشته باشه.

بعد اینکه استاد ، چرا سی شارپ ، عملگری برای محاسبه ی توان (توان در ریاضی) نداره (فقط متد Math.Pow داره) اما لوا که قابلیت های بسیار ضعیفی در ریاضیات داره ، این عملگر را داره!
#C عملگری برای توان نداره چون در ++C که بر اساسش طراحی شده هم چنین عملگری وجود نداشته. این عملگر رو ندارند به این خاطر که عملگر هاشون بر اساس عملیات اساسی پردازنده طراحی شده اند. محاسبه توان در دستورات اساسی پردازنده های کامپیوتر نیست. هر چیزی که باید با کد نویسی پیاده بشه رو به توابع کتابخانه ای واگذار کرده اند که قابل تغییر و جایگزینی است.

و یه چیز بسیار تعجب گرایانه برای من اینه که الان یه لینکی پیدا کردم که میگه یه چیزی بنام .Net Native داریم که همون کارایی زبان C++ Native را در . net framework ئه 4.5.1 و بالاتر (و انگار در ویندوز 10) ، ارائه میکنه . یعنی کدهای دات نت را دیگه به زبان IL و میانی ، کمپایل نمیکنه و مستقیما به کد زبان ماشین تبدیل میکنه :


من این همه خودمو پاره کردم گفتم ای کاش سی شارپ یه طراحی ای میکرد که کارایی اش شبیه C++ Native میبود (مثلا همین زبان میانی را نادیده میگرفت) ، یه چیزی درباره ی این .Net Native میگفتین ها :green:
البته از محدودیت هاش و اینکه چجوری بکار گرفته میشه و اینکه آیا همه ی قابلیت هایی که با .net framework ، در حالت عادی ای که میتونیم انجام بدیم را در اونجا هم میتونیم انجام بدیم یا نه را نمیدونم . فکر کنم مبحث خیلی جالبی باشه برای کسایی که بخوان با سی شارپ ، کارایی ای در حد C++ Native داشته باشن .
افزایش سرعت میده، که میزان اونم بستگی به کدی داره که کامپایلش می کنه، اما به این معنا نیست که کارایی اش در حد C++ Native بشه. کدی که در برنامه #C در حال اجرا است به زبان ماشین ترجمه شده که الان تونسته اجرا بشه، چه کامپایلرش Native باشه و چه نباشه نهایتا همین کد زبان ماشین تولید و اجرا میشه. اگر الان کد #C ای در اجرا کند ئه Native اش هم کند میشه، فقط موقع شروع اجرا سریعتر بالا میاد. اون کامپایلر Native تاخیر در اجرا رو که بخاطر مرحله کامپایل کد میانی بوده از بین میبره، در همین حد، نه بیشتر. خروجی همه زبان هایی که کامپایلر های Native دارند که سرعت یکسان ندارند.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
حد بالا و پایین نداره، چون بر اساس آرایه طراحی شده، هر چقدر لازم باشه آرایه بزرگتر میشه. تا جایی که بخاطر کمبود حافظه خطا بده یا از لحاظ تئوری طول آرایه به Int32.MaxValue برسه.


هر چیزی رو که میخواهید استفاده کنید اول توضیحاتش رو بخونید تا ببینید برای چه مواردی قابل استفاده است. sizeof برای همچین ساختاری قابل استفاده نیست.

آها یعنی بر اساس آرایه ای پویا هست که هر کدوم از عضوهای اون آرایه ، نوع int32 یا int64 هستن .
اگه این طوره ، هر عضوش ، باز محدود به مثلا int64 میشه و عددی بزرگتر از int64 را نباید بتونه توی خودش قرار بده . چجوری هه؟

افزایش سرعت میده، که میزان اونم بستگی به کدی داره که کامپایلش می کنه، اما به این معنا نیست که کارایی اش در حد C++ Native بشه. کدی که در برنامه #C در حال اجرا است به زبان ماشین ترجمه شده که الان تونسته اجرا بشه، چه کامپایلرش Native باشه و چه نباشه نهایتا همین کد زبان ماشین تولید و اجرا میشه. اگر الان کد #C ای در اجرا کند ئه Native اش هم کند میشه، فقط موقع شروع اجرا سریعتر بالا میاد. اون کامپایلر Native تاخیر در اجرا رو که بخاطر مرحله کامپایل کد میانی بوده از بین میبره، در همین حد، نه بیشتر. خروجی همه زبان هایی که کامپایلر های Native دارند که سرعت یکسان ندارند.

درباره جواب بقیه ی قسمت ها ، تشکر استاد .
استاد ، منظورتون اینه که .Net Native ، فقط زمان اجرای اپلیکیشن ، یعنی همون زمانی که برنامه مون رو شروع میکنیم ، یعنی زمان startup ئه برنامه مون سریعتر هه؟
یعنی مثلا در رویدادهای دیگه (مثلا در رویداد کلیکِ دکمه ای) کد بنویسیم ، سرعت اجراش فرقی با حالت معمولی (در حالت managed که زبان IL اش استفاده بشه) نداره؟
اگه منظورتون اینه ، چطوری هه؟ فرق زمان startup ئه برنامه با زمان ها و رویدادهای دیگه ، چیه؟!

---------------------------------------

و اینکه استاد ، سئوالات پست قبلی را به روزرسانی کرده بودم ، بی زحمت جواب میدین؟ :


و اینکه استاد ، در پروژه ی پشتیبانگیرم (که از alphavss استفاده میکرد) ، با توجه به این موارد ، شما چه نسخه از دات نت فریم وورک را توصیه میکنید؟
چون میخوام از alphavss v2.0 استفاده کنم ، این نسخه ، با .net framework 4.5 یا بالاتر سازگاره (مگر اینکه پیشنهاد بدید که از نسخه ی قبلی alphavss استفاده کنم) .
همچنین در wpf ، میخوام از قابلیت و کلاسِ WindowChrome هم استفاده کنم که انگار بصورت رسمی ، از نسخه ی .net framework 4.5 اضافه شد .
و از اونجایی که .net Native انگار روی .net framework 4.5.1 و بالاتر میتونه فعال بشه ، برای اینکه شاید در نسخه های بعد ، از این .net native استفاده کنم ، پس حداقل نسخه ی .net framework 4.5.1 را انتخاب کنم ، چطوره؟
تشکر استاد . :rose:
 

the_king

مدیرکل انجمن
آها یعنی بر اساس آرایه ای پویا هست که هر کدوم از عضوهای اون آرایه ، نوع int32 یا int64 هستن .
اگه این طوره ، هر عضوش ، باز محدود به مثلا int64 میشه و عددی بزرگتر از int64 را نباید بتونه توی خودش قرار بده . چجوری هه؟
چطوری دارید تحلیل می کنید؟ تصور کنید که هر رقم رو در یک خانه آرایه قرار داده اید، مثلا 5396 رو بصورت {5,3,9,6} تصور کنید.

استاد ، منظورتون اینه که .Net Native ، فقط زمان اجرای اپلیکیشن ، یعنی همون زمانی که برنامه مون رو شروع میکنیم ، یعنی زمان startup ئه برنامه مون سریعتر هه؟
اگه منظورتون اینه ، چطوری هه؟ فرق زمان startup ئه برنامه با زمان ها و رویدادهای دیگه ، چیه؟!
کامپایل فقط در زمان شروع اجرا نیست. اگر تمایل داشتید در مورد نحوه اجرای فایل های NET. مطالعه کنید، خودتون قبلا لینک در مورد ProfileOptimization داشتید که پاسخی که در پست #1,581 دادم مرتبط ئه.

یعنی مثلا در رویدادهای دیگه (مثلا در رویداد کلیکِ دکمه ای) کد بنویسیم ، سرعت اجراش فرقی با حالت معمولی (در حالت managed که زبان IL اش استفاده بشه) نداره؟
بله، تاثیر محسوسی نداره، چون احتمالا قبل از اینکه روی اون دکمه کلیک کنید فرصت کامپایل شدن رو پیدا کرده و کد Native حاضر ئه.

و اینکه استاد ، در پروژه ی پشتیبانگیرم (که از alphavss استفاده میکرد) ، با توجه به این موارد ، شما چه نسخه از دات نت فریم وورک را توصیه میکنید؟
چون میخوام از alphavss v2.0 استفاده کنم ، این نسخه ، با .net framework 4.5 یا بالاتر سازگاره (مگر اینکه پیشنهاد بدید که از نسخه ی قبلی alphavss استفاده کنم) .
همچنین در wpf ، میخوام از قابلیت و کلاسِ WindowChrome هم استفاده کنم که انگار بصورت رسمی ، از نسخه ی .net framework 4.5 اضافه شد .
و از اونجایی که .net Native انگار روی .net framework 4.5.1 و بالاتر میتونه فعال بشه ، برای اینکه شاید در نسخه های بعد ، از این .net native استفاده کنم ، پس حداقل نسخه ی .net framework 4.5.1 را انتخاب کنم ، چطوره؟
پایینترین نسخه ای که بهش نیاز دارید و با نسخه پایینتر نمیتوانید کار کنید. مثلا اگر با نسخه ای پایینتر از 4.5.1 به مشکل بر میخورید با 4.5.1.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
چطوری دارید تحلیل می کنید؟ تصور کنید که هر رقم رو در یک خانه آرایه قرار داده اید، مثلا 5396 رو بصورت {5,3,9,6} تصور کنید.

آها خیلی ممنون استاد .
یعنی هر عدد را داخل یه خونه از آرایه اش میفرسته؟! این جوری که میتونه یه عدد بسیار بسیار بسیار بسیار بزرگی را محاسبه کنه . فکر کنم فاکتوریلِ 1000 را هم بتونه محاسبه کنه (حساب نکردم ولی کلا میگم) البته اگه رمِ کاربر ، بتونه جواب بده .
جایی که عددِ UInt64.MaxValue را که عددِ 18446744073709551615هست ، فقط 20 خونه از آرایه اش (نسبت به تعداد خونه ی Int32.MaxValue از اون آرایه ، ازش اشغال میکنه) .

عملیاتِ ریاضی مثل جمع و تفریق اش هم مثل همون قضیه ی int64 و اینهاست؟ مثل این؟ :

C#:
BigInteger f = new BigInteger( UInt64.MaxValue) + new BigInteger( 3);

الان گفتید که تعداد خونه های آرایه ی BigInteger ، به اندازه ی Int32.MaxValue ، هست؟ اگه UInt32 اش را در نظر نگیریم و فقط Int32 اش را در نظر بگیریم ، یعنی تعدادِ ۲۱۴۷۴۸۳۶۴۷ خونه حافظه .
حالا آرایه اش از چه نوعی هست؟
به نظر میاد با این اوصافی که کردید ، برای صرفه جوییِ حافظه ، از نوعِ sbyte بهتره گرفته بشه .
اگه این طور باشه ، یعنی یه دونه شیِ BigInteger ، حداکثر میتونه چیزی نزدیک به 2 گیگ حافظه و بافر را میتونه حداکثر اشغال کنه ؟

کامپایل فقط در زمان شروع اجرا نیست. اگر تمایل داشتید در مورد نحوه اجرای فایل های NET. مطالعه کنید، خودتون قبلا لینک در مورد ProfileOptimization داشتید که پاسخی که در پست #1,581 دادم مرتبط ئه.


بله، تاثیر محسوسی نداره، چون احتمالا قبل از اینکه روی اون دکمه کلیک کنید فرصت کامپایل شدن رو پیدا کرده و کد Native حاضر ئه.

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

اگه آره ، خوب لازمه اش اینه که اول ProfileOptimization رو برنامه نویس فعال کرده باشه (و احتمالا هم پردازنده ی کاربر نهایی ، چند هسته ای بوده باشه) و مخصوصا اینکه اگه زمان رویداد کلیک (کلا رویدادی جز startup ئه برنامه) ، اگه حجم کد برای اجرا زیاد باشه (مثلا در یه کد بهینه ، 60 ثانیه یا خیلی بیشتر ، پردازنده را درگیر کنه) ، در این صورت ، در سرعت اجرا فرق دارن دیگه؟

چون کد برنامه ای که از .Net Native استفاده نمیکنه و قراره 60 ثانیه یا بیشتر در پردازنده اجرا بشه ، در این صورت ، آیا باز هم قبل از شروعِ کلیک روی دکمه (یعنی قبل از اینکه کد کلیک که 60 ثانیه زمان اجراش طول میکشه ، اجرا بشه) ، اون ProfileOptimization تجزیه و تحلیل کرده که قراره کلیک اتفاق بیفته و بعد کدِ کدهای اون رویداد کلیک را که زیاد هم هستن ، بیاد و به زبان CIL کمپایل کنه؟
اگه این کار را هم بتونه کامل وقبل از اجرای رویداد کلیک ، کل کدهاش را به CIL کمپایل کنه ، باز هم کمپایل به CIL ، خودش سربار داره برای پردازنده .
اگه هم نه و فقط بخشی از کدها را بتونه تا قبل از اجرای اون رویداد کلیک اجرا کنه (و بخشی را نتونه) ، بنابراین سرعت اجرا در پردازش های سنگین ، در .Net Native ، بالاتر میره .

اما اینکه کمپایلر .Net Native سرعتش به C++ Native نمیرسه ، خوب باز هم چندان اشکالی نداره . قطعا با حذف زبان CIL ، نسبت به .Net معمولی (یعنی بجز .Net Native) ، خیلی بیشتر از .Net معمولی ، به سرعت اجرای C++ Native ، نزدیک شد و گام بزرگی برای افزایش سرعت و کارایی مخصوصا در حجم کدهای پردازشی زیاد ، گرفت . هر چند سرعت کمپایلر .Net Native ، به C++ Native نرسه .
قبلا در سایتی دیده بودم که سرعت اجرای ++C با #C (با .Net معمولی) ، حداکثر حدود 2 برابر با ++C فرق داره .

پایینترین نسخه ای که بهش نیاز دارید و با نسخه پایینتر نمیتوانید کار کنید. مثلا اگر با نسخه ای پایینتر از 4.5.1 به مشکل بر میخورید با 4.5.1.

خودم نظرم اینه که بخاطر همه ی این مسائلی که گفتم ، از .Net Framework 4.5.1 استفاده کنم .
چون بعدا شاید از قضیه ی .Net Native هم استفاده کردم (شایدم نه . نمیدونم) .
و همچنین نسخه ی 4.5.1 که تاریخ انتشارش واسه 2013 هست ، چندان جدید هم نیست و تقریبا میشه گفت روی خیلی از ویندوزها ، حتی بصورت پیش فرض هم نصب هست (یا خودشون نصب میکنن) .

تشکر استاد
 

the_king

مدیرکل انجمن
آها خیلی ممنون استاد .
یعنی هر عدد را داخل یه خونه از آرایه اش میفرسته؟! این جوری که میتونه یه عدد بسیار بسیار بسیار بسیار بزرگی را محاسبه کنه . فکر کنم فاکتوریلِ 1000 را هم بتونه محاسبه کنه (حساب نکردم ولی کلا میگم) البته اگه رمِ کاربر ، بتونه جواب بده .
جایی که عددِ UInt64.MaxValue را که عددِ 18446744073709551615هست ، فقط 20 خونه از آرایه اش (نسبت به تعداد خونه ی Int32.MaxValue از اون آرایه ، ازش اشغال میکنه) .

عملیاتِ ریاضی مثل جمع و تفریق اش هم مثل همون قضیه ی int64 و اینهاست؟ مثل این؟ :

C#:
BigInteger f = new BigInteger( UInt64.MaxValue) + new BigInteger( 3);

الان گفتید که تعداد خونه های آرایه ی BigInteger ، به اندازه ی Int32.MaxValue ، هست؟ اگه UInt32 اش را در نظر نگیریم و فقط Int32 اش را در نظر بگیریم ، یعنی تعدادِ ۲۱۴۷۴۸۳۶۴۷ خونه حافظه .
حالا آرایه اش از چه نوعی هست؟
به نظر میاد با این اوصافی که کردید ، برای صرفه جوییِ حافظه ، از نوعِ sbyte بهتره گرفته بشه .
اگه این طور باشه ، یعنی یه دونه شیِ BigInteger ، حداکثر میتونه چیزی نزدیک به 2 گیگ حافظه و بافر را میتونه حداکثر اشغال کنه ؟
من نگفتم در BigInteger هر رقم در یک خونه قرار می گیره، گفتم فرض کنید که رقم ها در خانه های مجزای آرایه قرار بگیرند تا ببینید محدود به int64 نیست.
چرا دارید مثل حکایت فیل در تاریکی مثنوی معنوی تحلیل می کنید؟ کدش رو بررسی کنید و ببینید پیاده سازیش چطوریه دیگه.
 

SU-57

Active Member
سلام استاد علی

تشکر از شما و آقا سجاد برای پاسخ ها


1- چرا باید حتما از متد BigInteger.Multiply برای ضرب کردن استفاده کنیم؟ مثلا من کد رو اینجوری می نویسم خطا می گیره


کد:
BigInteger temp = Bigfactorial(n - 1) * new BigInteger(n));


کد اصلی هم که اینطوریه


کد:
  BigInteger temp = BigInteger.Multiply(Bigfactorial(n - 1), new BigInteger(n));


2- حالا اگه BigInteger.Multiply() رو در نظر بگیریم می تونیم بگیم که Multiply یک متد از استراکچر BigInteger ئه چون اگه بگیم عضوش هست ولی انگار مثل یک متد داره کاری انجام میده.

اصلا من آخرشنفهمیدم متد یک کلاس بودن چه فرقی با عضو یک کلاس یا استراکچر بودن داره مثل همین Multiply . اصلا عضو با متد فرقش چیه.
 

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

بالا