C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2010/07/20 01:52

null許容型は参照型と値型のどちらになるの?

C# だとローカル変数への代入は値渡ししかできません。
参照渡しで代入を行うようなコードを C# っぽく書いてみます。

Sample.cs
class Program
{
    static void Main()
    {
        int v0 = 0;
        int& v1 = v0;

        v0 = 5;
        System.Console.WriteLine(v0);
        System.Console.WriteLine(v1);
    }
}


このコードが動作するとすれば、v1 への代入が参照渡しになるので v1 からも 5 が取得されるはずですが、当然ながらこのコードはそもそもコンパイルできません。

しかし、IL ならばローカル変数への参照渡しができます。
先ほどのコードと同等のコードを IL で書くと次のようになります。

Sample.il
.assembly extern mscorlib { }
.assembly sample { }

.class private abstract auto ansi sealed beforefieldinit Program
    extends [mscorlib]System.Object
{
    .method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .locals init
        (
            [0] valuetype [mscorlib]System.Int32 v0,
            [1] valuetype [mscorlib]System.Int32& v1
        )

        // v0 = 0;
        ldc.i4.0
        stloc.0

        // v1 = v0;
        ldloca.s v0
        stloc.1

        // v0 = 5;
        ldc.i4.5
        stloc.0

        // Console.WriteLine(v0);
        ldloc.0
        call void [mscorlib]System.Console::WriteLine(int32)

        // Console.WriteLine(v2);
        ldloc.1
        ldind.i4
        call void [mscorlib]System.Console::WriteLine(int32)

        ret
    }
}


このコードを次のコマンドで exe ファイルとしてアセンブルします。

ilasm Sample.il


これを実行すると、v0 も v1 も 5 を返すことが確認できます。
つまり、v1 への参照渡しによる代入が可能であることが確認できます。



…まぁ、だからどうというわけでもないんですが。
IL で可能なので、C++/CLI でもできるかもしれませんね。

タグ: .NET C# CLR


つ ref
つ out

2010.08.21 11:48 URL | null #- [ 編集 ]


残念ながらそれらはローカル変数に使用できませんです

2010.08.23 17:22 URL | よこけん #Bpwahk/Q [ 編集 ]



それは参照渡しと言わないで、ポインタ渡しと言うんですけど?

2010.08.26 02:57 URL | null #- [ 編集 ]


いや、渡し方は値渡しか参照渡しのどちらかです。
ポインタ渡しというのは、ポインタの値渡しのことです。
記事の例をポインタ渡しにすると、次のようになります。

int* v1 = &v0;


# まぁ、そもそも値渡し・参照渡しというのは引数の渡し方の話なので、
# ローカル変数に参照渡しと表現するのは厳密には誤り、ということに今さら気付きました。。。

2010.08.26 08:59 URL | よこけん #Ay6tTHf6 [ 編集 ]












トラックバックURL↓
http://csharper.blog57.fc2.com/tb.php/286-8631fcb4

C# の隠しキーワード
C#と諸々 ローカル変数に参照渡しローカル変数に参照渡しはできないけれど、参照を扱うことはできるということに気付きました。実は C# には隠しキーワードがいくつかあって、その内の __makeref と __refvalu...

2011.03.22 00:04 | C#と諸々