有關行爲的假設是不正確的。
// Create a NEW array with the specified expressions which are evaluated
// immediately (to the current values of the fields)..
var array = new[] {name, id};
// Meaning it is equivalent to this .. note that the field names have
// NOTHING to do with the array object itself.
var array = new[] {(string)null, (string)null};
// Then for each item in the array, assign it a value
// (replacing what was already there anyway)
for (int i = 0; i < array.Length; i++) {
array[i] = "some string";
}
最後我們最終得到了一個看起來像["some string", "some string"]
的數組。再一次,與領域沒有「聯繫」。這個問題與參考類型無關(字符串是也參考類型)。
最好的(而且通常是正確的)方法是誠實地以不同的方式做到這一點。雖然人們可以換場接入/ setter和總有反射。如果是真正所需的動態名稱那麼字典或類似的或許應該被用來代替
下面是一個使用代理服務器的方法來包裝賦值操作。本示例使用Actions和"Statement Lambda" syntax。
var setters = new Dictionary<string, Action<Program, string>>() {
{ "name", (p, value) => p.name = value },
{ "id", (p, value) => p.id = value },
};
// For each field setter, assign a value (could use the name as a look-up)
foreach (var setter in setters.Values) {
setter(this, "some string");
}
這工作,因爲setter(..)
調用先前定義的實際行動分配給相應的成員。使用這種查找/代理(使用動作,函數或更復雜的類型)對於某些情況是有效的方法,但在不需要時應該避免。
這可以也可以用Reflection完成。
var t = this.GetType();
var fieldNames = new [] { "name", "id" };
var bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
foreach (var name in fieldNames) {
var fieldInfo = t.GetField(name, bindingFlags);
fieldInfo.SetValue(this, "some string");
}
反射通常應該是「最後的方法」。它丟失了靜態的輸入信息,將許多錯誤排除在運行時間之外,並且帶來了性能損失(這是可能的並不重要)。有一些非常漂亮的事情可以完成(特別是當表達式和註解也被使用時)..但反射是最好的,直到真正需要時才離開。
你可以通過使用反射,但你不應該。在這個assigment中:'array [i] =「some string」;''拋棄舊的引用,併爲'array [i]'賦值一個新值,這就是爲什麼它不會改變'name '。 – 2014-09-11 08:05:59
@ user2864740 - 好的。你能告訴如何爲p對象賦值數組中的相應字符串值嗎? – VVV 2014-09-11 08:06:03
爲什麼降價?這是正確的初學者問題... – 2014-09-11 08:06:10