int.TryParse перапісвае значэнне цэлага ліку, перададзеная ў якасцi выхаднога параметру

У мяне гэты код ...

var i = int.MinValue;
var s = string.Empty;
int.TryParse(s, out i);

Пасля TryParse Заява, значэнне ў я пераменная перапішуцца ( ў нуль ) і маё папярэдняе значэнне губляецца.

Ці з'яўляецца гэта памылка? Калі няма, то ці ёсць якія-небудзь дэталі рэалізацыі, чаму гэта было неабходна паўторна ініцыялізаваць зменную, якая перадаецца ў якасці з <�код /> параметр

3
Вам не трэба ініцыялізаваць I, замяніць першы радок з INT I; і код павінен працаваць.
дададзена аўтар Scott Chamberlain, крыніца
Вам не трэба ініцыялізаваць I, замяніць першы радок з INT I; і код павінен працаваць.
дададзена аўтар Scott Chamberlain, крыніца
<�Код> па змаўчанні (INT) == 0
дададзена аўтар Tim Schmelter, крыніца

10 адказы

Уся кропка з з'яўляецца тое, што гарантуе (ну, на ўзроўні # C, па меншай меры ... не ўзровень IL), каб перазапісаць гэта значэнне. Мэтай гэтага з'яўляецца пазбегнуць непатрэбных заданняў , дазваляючы пры гэтым «вызначанае прызначэнне». Напрыклад:

int i;//note: not assigned
var s = string.Empty;

// here "i" is not "definitely assigned"
int.TryParse(s, out i);
// here "i" is "definitely assigned"

Ідэя заключаецца ў тым, што вы выкарыстоўваеце вяртаецца значэнне, напрыклад:

if(int.TryParse(s, out i)) {
  //here "i" makes sense; feel free to use it
} else {
  //here you shouldn't use the value of "i"
}

У вашым канкрэтным выпадку, вы можаце замовіць дастаўку:

if(!int.TryParse(s, out i)) i = int.MinValue;

У прыватнасці, заўважым, што (у C#, па меншай меры) метад <�моцны> павінны </моцны> прысвоіць значэнне, і <�моцны> не можа </моцны> выкарыстоўваць якое ўваходзіць значэнне; напрыклад:

static void Foo(out int i) {
    return;//error: hasn't assigned to i
}
static void Bar(out int i) {
    int j = i;//error: cannot read from "i" until Bar has assigned a value
    i = j;
}
static void Baz(out int i) {
    i = 0;//note that after this assignment, code in Baz can read from "i"
}

Кантраснасць вых ; пры пераходзе </реф код> значэнне, то <�моцны> патрабуецца , каб быць вызначана прысвоенай у выклікалай праграме. Сам метад можа ці не можа глядзець на ўваходным значэнні (як ён выбірае), і можа ці не можа прысвоіць новае значэнне (як ён выбірае). Напрыклад:

int i;
SomeMethod(ref i);//illegal - "i" is not definitely assigned

int i = 0;
SomeMethod(ref i);//legal

а таксама:

static void Foo(ref int i) {
    return;//perfectly legal to not look at "i" and/or not assign "i"
}
static void Foo(ref int i) {
    i = i + 1;//perfectly legal to look at "i" and/or assign "i"
}
8
дададзена
Я іду, каб выбраць свой адказ у якасці адказу з-за яснага тлумачэння пытання і прыклады з выкарыстанняў па-за. Калі ласка, дадайце параўнання для спасылка у адказ, як добра, таму што я думаю, што калі зменная перадаецца як вых параметр, чым ён чакаў быць ініцыялізаваны ...
дададзена аўтар Naveed Butt, крыніца
@NaveedButt зроблена
дададзена аўтар Marc Gravell, крыніца

Уся кропка з з'яўляецца тое, што гарантуе (ну, на ўзроўні # C, па меншай меры ... не ўзровень IL), каб перазапісаць гэта значэнне. Мэтай гэтага з'яўляецца пазбегнуць непатрэбных заданняў , дазваляючы пры гэтым «вызначанае прызначэнне». Напрыклад:

int i;//note: not assigned
var s = string.Empty;

// here "i" is not "definitely assigned"
int.TryParse(s, out i);
// here "i" is "definitely assigned"

Ідэя заключаецца ў тым, што вы выкарыстоўваеце вяртаецца значэнне, напрыклад:

if(int.TryParse(s, out i)) {
  //here "i" makes sense; feel free to use it
} else {
  //here you shouldn't use the value of "i"
}

У вашым канкрэтным выпадку, вы можаце замовіць дастаўку:

if(!int.TryParse(s, out i)) i = int.MinValue;

У прыватнасці, заўважым, што (у C#, па меншай меры) метад <�моцны> павінны </моцны> прысвоіць значэнне, і <�моцны> не можа </моцны> выкарыстоўваць якое ўваходзіць значэнне; напрыклад:

static void Foo(out int i) {
    return;//error: hasn't assigned to i
}
static void Bar(out int i) {
    int j = i;//error: cannot read from "i" until Bar has assigned a value
    i = j;
}
static void Baz(out int i) {
    i = 0;//note that after this assignment, code in Baz can read from "i"
}

Кантраснасць вых ; пры пераходзе </реф код> значэнне, то <�моцны> патрабуецца , каб быць вызначана прысвоенай у выклікалай праграме. Сам метад можа ці не можа глядзець на ўваходным значэнні (як ён выбірае), і можа ці не можа прысвоіць новае значэнне (як ён выбірае). Напрыклад:

int i;
SomeMethod(ref i);//illegal - "i" is not definitely assigned

int i = 0;
SomeMethod(ref i);//legal

а таксама:

static void Foo(ref int i) {
    return;//perfectly legal to not look at "i" and/or not assign "i"
}
static void Foo(ref int i) {
    i = i + 1;//perfectly legal to look at "i" and/or assign "i"
}
8
дададзена
Я іду, каб выбраць свой адказ у якасці адказу з-за яснага тлумачэння пытання і прыклады з выкарыстанняў па-за. Калі ласка, дадайце параўнання для спасылка у адказ, як добра, таму што я думаю, што калі зменная перадаецца як вых параметр, чым ён чакаў быць ініцыялізаваны ...
дададзена аўтар Naveed Butt, крыніца
@NaveedButt зроблена
дададзена аўтар Marc Gravell, крыніца

Гэта не памылка, нуль вяртаецца, калі пераўтварэнне не ўдаецца. вяртаецца значэнне функцыі ў гэтым выпадку будзе ілжывым.

<�Р> Калі гэты метад вяртае, утрымлівае 32-разраднае цэлае значэнне   эквівалентна колькасці які змяшчаецца ў сек, калі пераўтварэнне атрымалася,   або нуль, калі пераўтварэнне не ўдалося. Пераўтварэнне не выконваецца, калі з   параметр мае нулявое значэнне, не правільны фармат, ці ўяўляе сабою   лік менш MinValue або больш, чым MaxValue. гэты параметр   перадаецца неинициализированным.

http://msdn.microsoft.com/en-us/library/f02979c7.aspx

5
дададзена

Гэта не памылка, нуль вяртаецца, калі пераўтварэнне не ўдаецца. вяртаецца значэнне функцыі ў гэтым выпадку будзе ілжывым.

<�Р> Калі гэты метад вяртае, утрымлівае 32-разраднае цэлае значэнне   эквівалентна колькасці які змяшчаецца ў сек, калі пераўтварэнне атрымалася,   або нуль, калі пераўтварэнне не ўдалося. Пераўтварэнне не выконваецца, калі з   параметр мае нулявое значэнне, не правільны фармат, ці ўяўляе сабою   лік менш MinValue або больш, чым MaxValue. гэты параметр   перадаецца неинициализированным.

http://msdn.microsoft.com/en-us/library/f02979c7.aspx

5
дададзена

<�моцны> з (C #) </моцны >

<�Р> Хоць зменныя, якія перадаюцца ў якасці аргументаў, выкананых не павінны быць ініцыялізаваны   да таго, як прайшло, <�моцны> выкліку метаду патрабуецца прызначыць   значэнне да вяртання метаду </моцны>. </р>

Int32.Parse initializes it with default(int) which is zero.

Калі гэты метад вяртае, утрымлівае 32-разраднае цэлы лік значэнне, эквівалентнае колькасці які змяшчаецца ў S , калі пераўтварэнне атрымалася, <�моцны> або нуль, калі пераўтварэнне не ўдалося </моцны>.

2
дададзена

<�моцны> з (C #) </моцны >

<�Р> Хоць зменныя, якія перадаюцца ў якасці аргументаў, выкананых не павінны быць ініцыялізаваны   да таго, як прайшло, <�моцны> выкліку метаду патрабуецца прызначыць   значэнне да вяртання метаду </моцны>. </р>

Int32.Parse initializes it with default(int) which is zero.

Калі гэты метад вяртае, утрымлівае 32-разраднае цэлы лік значэнне, эквівалентнае колькасці які змяшчаецца ў S , калі пераўтварэнне атрымалася, <�моцны> або нуль, калі пераўтварэнне не ўдалося </моцны>.

2
дададзена

Гэта не памылка, таму што гэта выхадны параметр. У якасці практыкаванні, паспрабуйце пісаць C#, які не ўстанаўлівае значэнне выхаднога параметра. (Падказка: Гэта немагчыма) Таму вынік вы назіраеце гэта адзіны лагічны адзін - з зменнай не «паўторна ініцыялізаваны», гэта проста ініцыялізуецца.

Калі TryParse была напісана, каб узяць реф Int тое, што вы хочаце, было б немагчыма. Асабіста я думаю, што з ИНТ лепш.

1
дададзена

Гэта не памылка, таму што гэта выхадны параметр. У якасці практыкаванні, паспрабуйце пісаць C#, які не ўстанаўлівае значэнне выхаднога параметра. (Падказка: Гэта немагчыма) Таму вынік вы назіраеце гэта адзіны лагічны адзін - з зменнай не «паўторна ініцыялізаваны», гэта проста ініцыялізуецца.

Калі TryParse была напісана, каб узяць реф Int тое, што вы хочаце, было б немагчыма. Асабіста я думаю, што з ИНТ лепш.

1
дададзена

Не, гэта не памылка, калі вы ўсталюеце на гэтае значэньне сек, напрыклад, «3»

var s = "3";

вы атрымаеце значэнне I будзе роўна 3

калі вы ўсталюеце string.Empty ён будзе роўны нулю, што з'яўляецца рэалізацыя па змаўчанні

вы паглядзіце на декомпилируемой код рэалізацыі можа

internal static unsafe bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result)
{
  byte* stackBuffer = stackalloc byte[114];
  Number.NumberBuffer number = new Number.NumberBuffer(stackBuffer);
  result = 0;
  if (!Number.TryStringToNumber(s, style, ref number, info, false))
    return false;
  if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
  {
    if (!Number.HexNumberToInt32(ref number, ref result))
      return false;
  }
  else if (!Number.NumberToInt32(ref number, ref result))
    return false;
  return true;
}

Вынік мае значэнне 0;

0
дададзена

Не, гэта не памылка, калі вы ўсталюеце на гэтае значэньне сек, напрыклад, «3»

var s = "3";

вы атрымаеце значэнне I будзе роўна 3

калі вы ўсталюеце string.Empty ён будзе роўны нулю, што з'яўляецца рэалізацыя па змаўчанні

вы паглядзіце на декомпилируемой код рэалізацыі можа

internal static unsafe bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result)
{
  byte* stackBuffer = stackalloc byte[114];
  Number.NumberBuffer number = new Number.NumberBuffer(stackBuffer);
  result = 0;
  if (!Number.TryStringToNumber(s, style, ref number, info, false))
    return false;
  if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
  {
    if (!Number.HexNumberToInt32(ref number, ref result))
      return false;
  }
  else if (!Number.NumberToInt32(ref number, ref result))
    return false;
  return true;
}

Вынік мае значэнне 0;

0
дададзена