C#:值型別和引用型別
之前有篇文章講到引數傳遞,https://blog.csdn.net/qq_38261174/article/details/84934444
但並未對值型別和引用型別做一個詳細的瞭解。
值型別和引用型別詳細的說明在右邊的網址中有:http://www.runoob.com/csharp/csharp-data-types.html
之前看了詳細說明,於是在我的腦海中就留下了一個印像,string是引用型別。對任何引用型別做了改變就會有影響。於是這句話在下面把我成功帶入坑。
今天早上看了一篇部落格,https://blog.csdn.net/luxin10/article/details/7178090
就講到了值型別和引用型別,我第一次看到題目我給出的答案也是錯的,看來還是被帶坑裡了。
題目是這樣的:
using System; public class Test1 { public static void Main() { int num = 0; Person p = new Person("Li"); A1(p, num); Console.WriteLine("{0},{1}", p.name, num); } static void A1(Person p, int num) { p = new Person("Wang"); num = 1; } } public class Person { public string name; public Person(string name) { this.name = name; } }
說說上面的程式產生的結果,以及產生這個結果的原因是什麼?
我想著不是很簡單嗎,因為Person是引用型別,對引用型別做了改變肯定會有影響,而int是值型別,則沒有影響。所以我第一次給出的答案是 : Wang 0
但是一執行,答案卻是 Li 0 ,這是為什麼呢?
我自己畫了上面這個圖,應該可以很好的理解了
但是我還看到了另一篇文章,我又有一個問題了,值型別真的不可以改變嗎?比如上面的 num在方法中做了改變,但最終輸出時卻毫無影響,這是值型別的特點。
那麼有一道題目是這樣的,如下:
public class Program {
static void Main(string[] args) {
int a = 4;
int b = 5;
Change(a,b); //自己按照要求完成這個方法
//要求如下:
Console.WriteLine("{0} {1}",a,b); //列印結果要為: 400 500
Console.ReadKey();
}
}
這不是很奇怪嗎?因為a,b是值型別,不管怎樣都是4和5啊,怎麼會打印出400和500呢
別跟我說a*100,b*100,作為一名程式設計師,那就真的有點說不過去了。
但是仔細想一想,有一種東西很奇特,那就是 反射,利用反射就可以做到。
之前有篇反射的使用文章可以瞭解下:https://blog.csdn.net/qq_38261174/article/details/84890229
很奇怪,我用c#語言試驗了一波,發現 反射居然也不能實現。希望知道的各位能給我答案。
我的程式碼如下:並沒有解決問題。
using System;
using System.Reflection;
namespace TestSuanfa {
public class Program {
static void Main(string[] args) {
int a = 4;
int b = 5;
Change(a,b); //自己按照要求完成這個方法 (實引數中沒有 ref,有ref就簡單了)
//要求如下:
Console.WriteLine("{0} {1}",a,b); //列印結果要為: 400 500
Console.ReadKey();
}
//我的Change方法如下,形參是自己定的,你也可以定義其它引數,只要符合題目要求就行了
public static void Change(int a, int b) {
Type type = typeof(int);
//值型別,預設屬性名 m_value 可通過 GetFields()打印出來得到
FieldInfo f = type.GetField("m_value",BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField);
object boxa = a;
object boxi = 100;
f.SetValue(boxa,boxi);
Console.WriteLine(f.GetValue(boxa));
}
}
}
列印如下,並沒有出現預料中的結果,希望解決的各位給我答案。
然後我用指標查看了a,b的地址,發現了原來是地址不一樣,所以無法解決。。
using System;
using System.Reflection;
namespace TestSuanfa {
public class Program {
static void Main(string[] args) {
int a = 4;
int b = 5;
unsafe {
Console.WriteLine("{0} {1}", (int)&a, (int)&b);
}
Change(a,b); //自己按照要求完成這個方法 (引數中沒有 ref,有ref就簡單了)
//要求如下:
Console.WriteLine("{0} {1}",a,b); //列印結果要為: 400 500
Console.ReadKey();
}
//我的Change方法如下,引數是自己定的,你也可以定義其它引數,只要符合題目要求就行了
public static unsafe void Change(int a, int b) {
Console.WriteLine("{0} {1}", (int)&a, (int)&b);
Type type = typeof(int);
//值型別,預設屬性名 m_value 可通過 GetFields()打印出來得到
FieldInfo f = type.GetField("m_value",BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField);
object boxa = a;
object boxi = 100;
f.SetValue(boxa,boxi);
Console.WriteLine(f.GetValue(boxa));
}
}
}
那麼那道題目是否有答案呢?