PDA

View Full Version : فلسفه عبارت New در تعریف یک متغیر !



online_mansoor2007
دوشنبه 19 فروردین 1387, 11:13 صبح
سلام
دوستان می خوام بدونم علت استفاده از عبارت New در تعریف یک متغیر چیه و برای چه منطوری ازش استفاده می شه؟ مثلاً مثل زیر :
Dim Cmd as new oledbcomand

ممنون .

baran_mehr
دوشنبه 19 فروردین 1387, 11:42 صبح
سلام دوست عزیز
ببین تو با این دستور فقط یک متغییر از نوع یک شئ تعریف کردی اما هنوز اون شئ رو ایجاد نکردی و نساختیش و قتی از new استفاده می کنی در واقع داری یک نمونه از اون شئ رو ایجاد میکنی و به اون متغییر نسبت میدی

titbasoft
دوشنبه 19 فروردین 1387, 11:55 صبح
در تکمیل پست قبل، شما زمانی که یک متغیر رو تعریف می کنید (declaration) مثل این می مونه که فقط یک پوینتر براش درنظر گرفته باشید. زمانی که اون رو با استفاده از کیورد New میاید Instantiate می کنید فضای مورد نیاز در حافظه برای ذخیره سازی اون متغیر در آدرس پوینتر مورد نظر ایجاد میشه.

Chabok
سه شنبه 20 فروردین 1387, 11:13 صبح
راستی DataReader چرا New نمیخواد ؟:لبخند:

جواب :
Why not "new SqlDataReader()" ?
(http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.adonet/topic9625.aspx)
There are no public constructors for SqlDataReader - if you could
construct one as above, what would you expect it to read?

You have to obtain a SqlDataReader reference from a call to a method of
another class - usually SqlCommand.ExecuteReader.

----
This is because your SqlCommand object is going to return to you an instance
of SqlDataReader. You never create a datareader object yourself.

if you did the following you would have two SqlDataReader objects in memory.
and the first one would no longer have a reference to it.
SqlDataReader dr = new SqlDataReader();
dr = SqlCommand.ExecuteReader();

dr is the following case is basically a pointer. The SqlCommand return the
object that dr points to.
SqlDataReader dr

موفق باشید . :)

reza6384
سه شنبه 20 فروردین 1387, 18:09 عصر
وقتی از new استفاده می کنید به مقدار سایز اون آبجکت ، از حافظه Heap بهش Allocate می شه، در ضمن بعضی آبجکت ها رو اگر New نکنید به مشکل Null Reference در زمان Runtime بر می خورید.

online_mansoor2007
سه شنبه 20 فروردین 1387, 23:46 عصر
وقتی از new استفاده می کنید به مقدار سایز اون آبجکت ، از حافظه Heap بهش Allocate می شه، در ضمن بعضی آبجکت ها رو اگر New نکنید به مشکل Null Reference در زمان Runtime بر می خورید.

اتفاقاً منم یه جا به همین مشکل برخوردم که با زدن new مشکلم حل شد . اما توضیحتون یکم گنگ بود یا شایدم من گیجم . اگه میشه دوستان بیشتر و واضح تر توضیح بدید

ممنون

reza6384
چهارشنبه 21 فروردین 1387, 00:09 صبح
با یک مثال ساده توضیح می دم، فرض کنید یک کلاس داریم به نام Student که دارای Property های Name از نوع Char و 20 حرفی، Family از نوع Char و 20 حرفی + سال ورود از نوع Int16 و شماره دانشجویی از نوع Int32 .
جمع حافظه ای که یک آبجکت از این کلاس می خواد 46 بایته.
وقتی می نویسیم :


Dim ST1 As New Student


46 بایت حافظه به این آبجکت ST1 اختصاص داده می شه و حالاست که می تونیم Property های اون رو مقداردهی کنیم. چون هر کدوم Property ها یک جایی در حافظه دارن. اما اگر بنویسیم :



Dim ST1 As Student
ST1.Name = "Ali"


با مشکل Null Reference مواجه می شیم چون ST1 به جایی از حافظه اشاره نمی کنه که دو رشته 20 حرفی و دو تا عدد صحیح باشه . یعنی برای این Property ها حافظه ای اختصاص داده نشده که مقداره بره اونجا بشینه!!

راجع به تخصیص حافظه هم بگم که سه نوع داریم :

1-Static Allocation :
یعنی حافظه در زمان Compile اختصاص داده می شه و ثابته و این باعث می شه که
مثلا امکان فراخوانی بازگشتی نداشته باشیم.

2-Stack Allocation :
حافظه مثل یک پشته اختصاص داده می شه و این امکان Recursive Call رو فراهم می کنه.

3- Heap Allocation :
توی این نوع تخصیص ، برای متغیر ها از هر جای حافظه، حافظه اختصاص می شه و بعدا هم با استفاده از Dispose یا Garbage Collection این حافظه ها آزاد می شن.

امیدوارم که منظورم رو واضح و بدون غلط بیان کرده باشم.

online_mansoor2007
چهارشنبه 21 فروردین 1387, 09:02 صبح
سلام

رضا جان واقعاً ممنون . خیلی عالی بود .
اما یه سول چرا OLEDBDataReader عبارت NEW را نیاز نداره؟؟؟؟؟؟؟؟؟؟

علیرضا مداح
چهارشنبه 21 فروردین 1387, 10:00 صبح
سلام ،
اشیائی که اینترفیس IDataReader را Implement میکنند وظیفه برگرداندن یک استریم Forward-Only از مجموعه سطرها را بر عهده دارد که اینکار توسط متد ExecuteReader مربوط به کلاسی صورت میگیرد که اینترفیس IDbCommand را Implement میکند و شیء IDataReader هیچ متدی برای ست کردن فیلدهای Row ها و یا اضافه نمودن Row جدید ندارد ، پس در نتیجه Instantiate نمودن آن بیمورد است.

online_mansoor2007
چهارشنبه 21 فروردین 1387, 11:05 صبح
سلام .
تو رو خدا در حد ما بی سوادا حرف بزنید !!!!!!!! علیرضا جون یکم بازش کن عزیز

علیرضا مداح
چهارشنبه 21 فروردین 1387, 11:41 صبح
دوست عزیز توجه کنید که اگر شما بتواتید توسط کلیدواژه New یک نمونه(Instance) از شیء دیتاریدر در حافظه بسازید ، چگونه میخواهید آن را پر(Fill) کنید؟ چون همانطور که گفتم این شیء یک جریان Forward-Only در اختیار شما میگذارد ، یعنی شما فقط امکان MoveNext را در اختیار خواهید داشت و اجازه ی اضافه و یا تغییر محتویات یک رکورد را نداشته و در صورت نمونه سازی(Instantiate) آن هیچ داده ای برای خواندن نخواهید داشت ،
دقت کنید از نام این شی ء هم پیداست DataReader ، بدین معنی که تنها وظیفه خواندن(Read) اطلاعات را بر عهده خواهد داشت ----->این شی ء دارای Public Constructor نیست.

online_mansoor2007
چهارشنبه 21 فروردین 1387, 12:21 عصر
سلام .
واقعاً ممنون . در واقع DataReader یک واستس بین یه شی مثل command و یک Datagrid درسته ؟ یعنی اطلاعات را از command میگیره میده به DataGrid . درسته؟ چون در واقع کار نگهداری اطلاعات را انجام نمیده نیازی هم به حافظه نداره . درسته ؟

علیرضا مداح
چهارشنبه 21 فروردین 1387, 12:50 عصر
نه ، دیتاریدر ربطی به دیتاگرید ندارد ، ولی دیتاریدر حجم حافظه ی کمتری نسبت به دیتاست اشغال می نماید ، به دلیل اینکه دیتاریدر تنها یک رکورد را در هر زمان بر میگرداند و هر زمان که متد Read مربوط به آن فراخوانی شود ، دیتاریدر با رکورد بعدی پر میشود ، یعنی تا زمانیکه ارتباط دیتاریدر با دیتابیس برقرار است شما توانایی خواندن مقادیر رکوردهای آن را دارید . توجه کنید که دیتاریدر مشخصه های کلی زیر رار دارد:


Read-Only
Forward-Only
Connected

titbasoft
چهارشنبه 21 فروردین 1387, 15:25 عصر
سلام ،
اشیائی که اینترفیس IDataReader را Implement میکنند وظیفه برگرداندن یک استریم Forward-Only از مجموعه سطرها را بر عهده دارد که اینکار توسط متد ExecuteReader مربوط به کلاسی صورت میگیرد که اینترفیس IDbCommand را Implement میکند و شیء IDataReader هیچ متدی برای ست کردن فیلدهای Row ها و یا اضافه نمودن Row جدید ندارد ، پس در نتیجه Instantiate نمودن آن بیمورد است.
علیرضا جون با اجازت من یه کم ساده تر این مساله توضیح می دم: (رخصت)

اصلا ذهنتون رو از DataReader پاک کنید..... شما به هر طریقی باید فضای مورد نیاز در حافظه رو Allocate کنید. حالا این فضا می تونه یک فضای جدید باشه، که با کیورد New بوجود میاد، یا می تونه قبلا توسط متغیر دیگری Allocate شده باشه و حالا شما بگید که متغیر جدید شما هم از همون فضا استفاده کنه، که همین حالتی میشه که برای DataReader اتفاق میافته. در حقیقت در زمان اجرای Command این فضا ساخته میشه، تغیرات مورد نیاز درش داده میشه و در اختیار شما قرار میگیره تا باهاش کار کنید. شما هم براش یه اسم جدید میزارید به نام DataReader و مجددا میگید با همون فضای Allocate شده کار کن. (چیزی شبیه به اینکه 2 تا Piointer به یک فضا اشاره کنند)

علیرضا مداح
چهارشنبه 21 فروردین 1387, 17:29 عصر
در تصریح فرمایشات هاشم جان ، هنگام اجرای Command ، یک نمونه (Instance) از شی ء DataReader در حافظه ایجاد و فضای مورد نیاز به آن تخصیص داده میشود و شما فقط یک پوینتر از نوع IDataReader برای کار با آن میسازید.

reza6384
چهارشنبه 21 فروردین 1387, 23:00 عصر
ببین، وقتی یک کلاس عضوی نداشته باشه که بخواد توسط کاربر مقدار دهی بشه و فقط متدهاش فراخوانی بشن، دیگه احتیاجی به new کردن نداره، اگر مثلا کلاس مذکور یک متد داشته باشه و متدش چند تا متغیر ، اون متغیرها فقط در زمان حیاط یا Scope اون تابع ایجاد می شن و بعد از فراخوانی از بین می رن. پس دیگه احتیاجی نداره که New بشه.
مثلا همین SqlDataReader رو ، Property هاش رو نگاه کن :



Dim I as SqlClient.SqlDataReader
I.

ببین توی لیستی که باز می شه همش نوشته Gets the ..... و هیچ جا Set نداره.

ولی مثلا یک آبجکت از کلاس Dataset یک سری Property داره که Set می شن و ایناس که New می شه.

اما اگر بازهم متوجه چیزی نشدی بگو.