Это один из тех случаев, когда измерение влияет на результат.
Основной причиной является оптимизация компилятором (обратная?) Для улучшения локальных параметров во время отладки.
Когда вы пишете:
let list1 = [1; 2; 3]
let list2 = [3; 4; 5]
printfn "%b" (list1 = list2)
Это уточняет каждое подвыражение:
let list1 = [1; 2; 3]
let list2 = [3; 4; 5]
let list1' = list1
let list2' = list2
let is_eq = list1'.Equals(list2')
printfn "%b" (is_eq)
Теперь вы можете начать догадываться, куда это идет.
Console.WriteLine("IsAlive: {0}\nobj <> null is {1}\n---", weak.IsAlive, obj <> null);
Уточняется:
let isAlive = weak.IsAlive
let obj' = obj
let isNotNull = obj' <> null
Console.WriteLine("IsAlive: {0}\nobj <> null is {1}\n---", isAlive, isNotNull);
Теперь, когда вы сделаете:
obj <- null;
GC.Collect();
обратите внимание, что ссылка все еще существует в obj'
.
Таким образом, объект не будет собран во время прохода G C. И это то, что показывает WeakReference
.
Достаточно интересно, что если вы закомментируете первое Console.Writeline
, нет никакой детализации подвыражения, следовательно, нет ссылок, и вы получите:
IsAlive: False
Или вы можете просто построить его в режиме Release .