トップ回答者
言語仕様(2.0、3.0)の違いによるエラーでしょうか?

質問
-
C#2.0では、正常にコンパイルできていたのですがC#3.0ではコンパイルエラーになってしまいます。
コードの下線でエラーになります。「ref またはout引数は、割り当て可能な変数でなければなりません」
言語仕様の変更によるものでしょうか? 言語仕様のどこに記述がありますか?
実際はどっちが正しいのでしょうか?
知ってる方、宜しくお願いいたします。
class test { void proc1(ref short s) { } void proc2(short s) { short s = 0; proc1(ref (short) s); } }
回答
-
回答ではないですがお邪魔させていただきます。proc2 の引数sと変数sが重複するのでそこは回避して動作確認しました。で、ちょっと実験、、、proc1(ref (short)ss);↓proc1(ref ss++);でも同じエラーになります。ss++ は明確に値型なのでこれは当然。
これを Visual Studio 2003 の環境でビルドすると「ref または out 引数は左辺値でなければなりません。」というエラーになります。
さらに実験、、、int a=1, b=2, c=4;(int)a = b + c;と書くと、2003 ではエラーになりませんが2008 では「代入式の左辺には変数、プロパティ、またはインデクサを指定してください。」というエラーになりました。
これらのことから“昔は (int)a みたいな書き方しても変数参照(左辺値)とみなしてくれたんだ”というところは見えてくるような気がします。
これが C# 2.0 と 3.0 の違いかどうかについては、双方の言語仕様の該当しそうな箇所を見ましたが違いは解りませんでした。言語仕様とコンパイラ仕様が別物だとして、C# 3.0 ではいろいろ書き方が増えたためチェックを厳しくしないとコンパイラが対応できなかったのではないかと憶測しています。
-
こんにちは。
#proc2メソッドの「short s = 0;」の行はケアレスミスですよね、きっと
「(short) s」は式です。
ref は変数の格納場所を渡す文法です。(まあ、アドレスですね)
なのでエラーになるのが正しいと思います。
C#コンパイラはバージョンが上がるたびに重箱の隅な穴をふさいできているので、それで修正されたのだと思います。
すべての返信
-
回答ではないですがお邪魔させていただきます。proc2 の引数sと変数sが重複するのでそこは回避して動作確認しました。で、ちょっと実験、、、proc1(ref (short)ss);↓proc1(ref ss++);でも同じエラーになります。ss++ は明確に値型なのでこれは当然。
これを Visual Studio 2003 の環境でビルドすると「ref または out 引数は左辺値でなければなりません。」というエラーになります。
さらに実験、、、int a=1, b=2, c=4;(int)a = b + c;と書くと、2003 ではエラーになりませんが2008 では「代入式の左辺には変数、プロパティ、またはインデクサを指定してください。」というエラーになりました。
これらのことから“昔は (int)a みたいな書き方しても変数参照(左辺値)とみなしてくれたんだ”というところは見えてくるような気がします。
これが C# 2.0 と 3.0 の違いかどうかについては、双方の言語仕様の該当しそうな箇所を見ましたが違いは解りませんでした。言語仕様とコンパイラ仕様が別物だとして、C# 3.0 ではいろいろ書き方が増えたためチェックを厳しくしないとコンパイラが対応できなかったのではないかと憶測しています。
-
プロジェクトプロパティのアプリケーションタブに「対象のフレームワーク」があり、そこでアプリケーションが使用する
FrameWorkのバージョンが選択できます。
試しに、提示されているコードを2.0と3.0の2つで試してみましたが、両方ともCS1510コンパイルエラーが発生します。
実際にVS2005で2.0のみの環境では試していませんのでなんとも言えません。
CA系の警告ならプロジェクトの設定を疑うのですが・・・
なお、anningoさんの仰る様に、同様に、キャストにも以下が言えます。
proc1(ref s);
sは、メソッドの引数が値渡しで受け取っているので、メソッド内での実体をもつのでOK
proc1(ref (short) s);
short型にキャストされたsはどこにも代入されておらず、参照渡し元の実体が定義されていないことになりNG
short hoge = (short)s; proc1(ref hoge);
short型にキャストされたsは、一旦hogeという実体に代入され、参照渡し元の実体が定義されていることになりOK -
こんにちは。
#proc2メソッドの「short s = 0;」の行はケアレスミスですよね、きっと
「(short) s」は式です。
ref は変数の格納場所を渡す文法です。(まあ、アドレスですね)
なのでエラーになるのが正しいと思います。
C#コンパイラはバージョンが上がるたびに重箱の隅な穴をふさいできているので、それで修正されたのだと思います。