PDA

View Full Version : میدان دید متغیر ها در بلاک های: for, foreach, try و...



C#Master
یک شنبه 06 آبان 1386, 23:18 عصر
هنگام کد نویسی در C# 2005 به مشکلی در میدان دید متغیرها برخوردم. موقعی که یک متغییر بطور خاص یک متغییر Refrence Type که از بد حادثه Abstract هم هست، قراره مثلا داخل بلاک Try توسط یک متد از شیئ دیگه ای New بشه.

اگر همون داخل try تعریفش کنم بیرون try شناخته شده نیست، اگر بیرون try تعریف کنم و داخل try توسط متد دیگری new کنم ایراد میگیره که:

!Use of unassigned local variable X

راه حل این مشکل چیه؟

این هم نمونه کدی این مشکل رو باهاش دارم:





public static DataTable GetData(string Command)
{
OleDbDataReader OleDbdr;
DataTable outputTable;
string ConStr = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/trfc.mdb") + ";Jet OLEDB:System Database=system.mdw;User ID=admin;Password=;";
OleDbConnection Conn = new OleDbConnection(ConStr);
OleDbCommand Com = new OleDbCommand(Command, Conn);
try
{
Conn.Open();
OleDbdr = Com.ExecuteReader();
outputTable = GetTable(OleDbdr); // Returns DataTable
}
catch (Exception e)
{
}
finally
{
Conn.Close();
return outputTable;
}
}

MohammadSoft
یک شنبه 06 آبان 1386, 23:33 عصر
سلام
الان تو این کدی که شما گذاشتید چه ایرادی می گیره و از چه متغیری ؟

mehdi.mousavi
دوشنبه 07 آبان 1386, 00:14 صبح
هنگام کد نویسی در C# 2005 به مشکلی در میدان دید متغیرها برخوردم. موقعی که یک متغییر بطور خاص یک متغییر Refrence Type که از بد حادثه Abstract هم هست، قراره مثلا داخل بلاک Try توسط یک متد از شیئ دیگه ای New بشه.

اگر همون داخل try تعریفش کنم بیرون try شناخته شده نیست، اگر بیرون try تعریف کنم و داخل try توسط متد دیگری new کنم ایراد میگیره که:

!Use of unassigned local variable X

راه حل این مشکل چیه؟

این هم نمونه کدی این مشکل رو باهاش دارم:






public staticDataTable GetData(string Command)

{
OleDbDataReader OleDbdr;
DataTable outputTable;
string ConStr = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/trfc.mdb") + ";Jet OLEDB:System Database=system.mdw;User ID=admin;Password=;";
OleDbConnection Conn = newOleDbConnection(ConStr);
OleDbCommand Com = newOleDbCommand(Command, Conn);
try

{
Conn.Open();
OleDbdr = Com.ExecuteReader();
outputTable = GetTable(OleDbdr);
}
catch (Exception e)
{
}
finally

{
Conn.Close();
}

return outputTable;
}







سلام.
متغیر رو بیرون try تعریف کنید و هنگام تعریف مساوی null بذارید. سپس اونو در try میتونید new کنید و در finally هم بهش دسترسی داشته باشید و دیگه پیام Use of unassigned local variable رو هم نخواهید گرفت.

البته شما نوشتید کلاستون abstract هستش، برام جالبه که بدونم چطوری میخواهید یه کلاس abstract رو new کنید! چنین چیزی اصلا امکانپذیر نیست.

C#Master
چهارشنبه 09 آبان 1386, 20:11 عصر
آقا مهدی، از پاسخ شما تشکر میکنم.

اولا منظورم از new کردن یک شیئ از یک کلاس Abstract ایجاد Content برای آن متغیر توسط متدی هز کلاس دیگر بو که البته از عبارت مناسبی استفاده نکردم. مثلا برای یک متغییر از نوع DataRow میتوان از طرییق اجرای متد DataTable.NewRow محتوا (Content) ایجاد کرد.

ثانیا راه پیشنهادی شما در مورد مشکلی که من دارم عملی نیست، من داخل بلاک Try قصد مقدار دادن به متغییری رو دارم که بعد از این بلاک باید با دستور return به عنوان مقدار خروجی یک تابع بازگردانده بشه، حالا نه میتونم دستور return رو داخل finally قرار بدم (چون error میده) و نه میتونم بیرون بلاک Try به متغیری که داخل این بلاک براش محتوا تعیین کردم دسترسی داشته باشم!

واقعا این مسئله باید پیش پا افتاده باشه و راه حل معقولی داشته باشه، فقط مسئله اینه که اون راه حل چیه؟!؟!؟

mehdi.mousavi
پنج شنبه 10 آبان 1386, 00:20 صبح
آقا مهدی، از پاسخ شما تشکر میکنم.

اولا منظورم از new کردن یک شیئ از یک کلاس Abstract ایجاد Content برای آن متغیر توسط متدی هز کلاس دیگر بو که البته از عبارت مناسبی استفاده نکردم. مثلا برای یک متغییر از نوع DataRow میتوان از طرییق اجرای متد DataTable.NewRow محتوا (Content) ایجاد کرد.

ثانیا راه پیشنهادی شما در مورد مشکلی که من دارم عملی نیست، من داخل بلاک Try قصد مقدار دادن به متغییری رو دارم که بعد از این بلاک باید با دستور return به عنوان مقدار خروجی یک تابع بازگردانده بشه، حالا نه میتونم دستور return رو داخل finally قرار بدم (چون error میده) و نه میتونم بیرون بلاک Try به متغیری که داخل این بلاک براش محتوا تعیین کردم دسترسی داشته باشم!

واقعا این مسئله باید پیش پا افتاده باشه و راه حل معقولی داشته باشه، فقط مسئله اینه که اون راه حل چیه؟!؟!؟

سلام.
متوجه منظورتون نمیشم! به این کد نگاه کنید:


private Int32 GetNumber()
{
Int32 a = 0;
try
{
a = 5;
}
catch
{
a++;
}
finally
{

}

return a;
}



الان متغییر a خارج از try تعریف شده، سپس در داخل خود try، مقدار دهی شده، و همینطور در catch block هم یه واحد بهش اضافه میشه. تو finally هم هر کاری بخوام میتونم با a انجام بدم و در نهایت مقدار a هم بعنوان خروجی تابع به بیرون بر میگرده.

این دقیقا همونکاری هستش که شما میخواهید انجام بدین. شما نباید سعی کنید که تو finally block از return استفاده کنید، چون این کار بی معنی هستش. شما فقط باید در دو حالت try و catch یه مقدار رو به بیرون بر گردونید:


private Int32 GetNumber()
{
Int32 a = 0;
try
{
return 0;
}
catch
{
return 1;
}
finally
{
}



این کد هم کد صحیحی هستش، اگر چه به نظر میرسه که در finally block باید مقداری return بشه، اما اینطور نیست. اگر مشکلی در try پیش نیاد، مقدار صفر به بیرون برگردونده میشه اما قبل از بازگشت finally block فراخوان میشه. اما اگر در try یه exception ای رخ بده، اونوقت مقدار 1 به بیرون بر گردونده میشه، اما بازم قبلش finally block فراخوان میشه. پس میبینید که هیچوقت حالتی پیش نمیاد که نیاز به یه return سوم باشه! بازم اگر سوالی بود، من در خدمتم.

LazyComputerStudent
سه شنبه 02 بهمن 1386, 00:28 صبح
منم همین مشکل رو دارم. از NetworkStream و TcpClient استفاده می کنم. که ممکنه تو ایجاد خودش (new) مشکل پیش بیاد و باید error نشون بده ، نمیشه خارج از بلوک try باشه. اما میخوام حتما بسته بشه، باید در finally باشه. چه جوری این مشکل حل میشه؟ ممنون میشم راهنمایی کنید

LazyComputerStudent
سه شنبه 02 بهمن 1386, 00:51 صبح
البته من اینو امتحان کردم



سلام.
متغیر رو بیرون try تعریف کنید و هنگام تعریف مساوی null بذارید. سپس اونو در try میتونید new کنید و در finally هم بهش دسترسی داشته باشید و دیگه پیام Use of unassigned local variable رو هم نخواهید گرفت.



درست شد. می خواستم بدونم روش کار همینه؟ یعنی همیشه باید همین کارو واسه این مشکل انجام داد؟

mahdi_farhani
سه شنبه 02 بهمن 1386, 09:11 صبح
اصلاً قانونو اینه که بعد از هر تعریف متغییر اونو مقدار دهی کنی