次のコードは、結果として割り当てられていないローカル変数 "numberOfGroups"の使用になります。
int numberOfGroups;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
numberOfGroups = 10;
}
ただし、このコードは正常に機能します(ただし、 ReSharper は= 10
が冗長であると言っています):
int numberOfGroups = 10;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
numberOfGroups = 10;
}
何かが足りないのですか、それともコンパイラが私の||
を気に入らないのですか?
これをdynamic
に絞り込んだため、問題が発生しました(options
は上記のコードでは動的変数でした)。質問はまだ残っています、なぜ私はこれを行うことができないのですか?
このコードしないコンパイル:
internal class Program
{
#region Static Methods
private static void Main(string[] args)
{
dynamic myString = args[0];
int myInt;
if(myString == null || !int.TryParse(myString, out myInt))
{
myInt = 10;
}
Console.WriteLine(myInt);
}
#endregion
}
ただし、このコードdoes:
internal class Program
{
#region Static Methods
private static void Main(string[] args)
{
var myString = args[0]; // var would be string
int myInt;
if(myString == null || !int.TryParse(myString, out myInt))
{
myInt = 10;
}
Console.WriteLine(myInt);
}
#endregion
}
dynamic
がこれの要因になるとは思いませんでした。
これはコンパイラのバグだと確信しています。素敵な発見!
編集:Quartermeisterが示すように、これはバグではありません。動的に奇妙なtrue
演算子が実装され、y
が初期化されない可能性があります。
最小限の再現は次のとおりです。
class Program
{
static bool M(out int x)
{
x = 123;
return true;
}
static int N(dynamic d)
{
int y;
if(d || M(out y))
y = 10;
return y;
}
}
それが違法であるべき理由はわかりません。 dynamicをboolに置き換えると、正常にコンパイルされます。
私は実際に明日C#チームと会います。私は彼らにそれについて言及します。エラーをお詫びします!
動的式の値がoverloaded true
operatorの型である場合、変数が割り当て解除される可能性があります。
||
演算子はtrue
演算子を呼び出して右側を評価するかどうかを決定し、次にif
ステートメントはtrue
演算子を呼び出して右辺を評価するかどうかを決定しますその体。通常のbool
の場合、これらは常に同じ結果を返すため、正確に1つが評価されますが、ユーザー定義の演算子の場合、そのような保証はありません。
Eric Lippertの再現を基に、どちらのパスも実行されず、変数の初期値が設定される場合を示す、短くて完全なプログラムを次に示します。
using System;
class Program
{
static bool M(out int x)
{
x = 123;
return true;
}
static int N(dynamic d)
{
int y = 3;
if (d || M(out y))
y = 10;
return y;
}
static void Main(string[] args)
{
var result = N(new EvilBool());
// Prints 3!
Console.WriteLine(result);
}
}
class EvilBool
{
private bool value;
public static bool operator true(EvilBool b)
{
// Return true the first time this is called
// and false the second time
b.value = !b.value;
return b.value;
}
public static bool operator false(EvilBool b)
{
throw new NotImplementedException();
}
}
MSDNから (私の強調):
動的型は、それが発生する操作をコンパイル時の型チェックをバイパスすることを可能にします。代わりに、これらの操作は実行時に解決されます。動的タイプは、OfficeオートメーションAPIなどのCOM API、IronPythonライブラリなどの動的API、およびHTMLドキュメントオブジェクトモデル(DOM)へのアクセスを簡素化します。
動的型は、ほとんどの状況でオブジェクト型のように動作します。ただし、動的型の式を含む演算は、コンパイラによって解決または型チェックされません。
コンパイラーは、動的型の式を含む操作を型チェックまたは解決しないため、TryParse()
を使用して変数が割り当てられることを保証できません。