ネタ元>[日常][C/C++][VB]VBでこんな書き方出来るの?
void test1(){
char str1[] = "aaaa";
char str2[] = "bbbb";
char *array[] = {str1, str2};
for (int i=0; i<2; i++){
strcpy(array[i],"cccc");
}
printf("%s\n", str1); // "cccc"が表示される事を期待
printf("%s\n", str2); // "cccc"が表示される事を期待
}
void test2(){
char *str1 = "aaaa";
char *str2 = "bbbb";
char **array[] = {&str1, &str2};
for (int i=0; i<2; i++){
*array[i] = "cccc";
}
printf("%s\n", str1); // "cccc"が表示される事を期待
printf("%s\n", str2); // "cccc"が表示される事を期待
}
Cのコードはこのどちらかを意図していると思います。
でも、双方のコードは結果は同じでもやってることが違います。
test1の関数は、str1,str2を変更することができないので
str1,str2が参照しているデータを書き換えています。
test2の関数は、str1,str2のアドレスを持っているため、
この変数そのものの値を書き換えています。
test1 の様子 |
test2の様子 |
 |
 |
で、.Netのコードでこれをやろうとすると、どっちもできません。
test1の方法ではString型がReadonlyのため書き換えることができず、
test2の方法ではアドレスを取得できないため、
str1,str2に別名でアクセスする方法がありません。
ただ、test1の方法でString以外を使う方法でなら実現できます。
たとえばStringBuilderを使ったらこんな感じ。
static void Test1(){
var str1 = new System.Text.StringBuilder("aaaa");
var str2 = new System.Text.StringBuilder("bbbb");
System.Text.StringBuilder[] array = { str1, str2 };
for (int i = 0; i < 2; i++){
array[i].Remove(0, array[i].Length);
array[i].Append("cccc");
}
Console.WriteLine(str1);
Console.WriteLine(str2);
}
StringBuilderは全部置き換えを目的に作られてないため、
RemoveしてAppendという情けないコードになってますが…。
ただ、こんな苦し紛れなことをするよりは、器に入れて持ち運んでやるべきでしょうね。
public class Carrier{
public T value;
public Carrier(T x){
value = x;
}
}
static void Test2()
{
var str1 = new Carrier("aaaa");
var str2 = new Carrier("bbbb");
Carrier[] array = { str1, str2 };
for (int i = 0; i < 2; i++){
array[i].value = "cccc";
}
Console.WriteLine(str1.value);
Console.WriteLine(str2.value);
}
#まだ.Net Refrector入れてないのでVBじゃなくてC#だけど…