Противопоказание потеряно для параметров ref
и out
, поскольку они являются ссылками. Это означает, что когда вы передаете нормальный параметр методу, CLR решит эту ссылку на значение и передаст это значение в качестве аргумента, тогда как когда параметр имеет значение ref
или out
, CLR передаст всю ссылку как аргумент. Тип ссылки в .NET - WeakReference<T>
, и вы включаете в него свою ссылку.
Общий аргумент, заданный для WeakReference<T>
, является типом, на который вы ссылаетесь, например:
public void Test<T>(ref T reference)
{
WeakReference<T> weakReference = __makeref(reference);
}
Теперь я углублюсь в другой пример:
public void Test(ref string reference)
{
WeakReference<string> weakReference = __makeref(reference);
}
И это еще один:
public void Test(ref string reference)
{
WeakReference<object> weakReference = __makeref(reference);
}
Последний пример выдаст вам ошибку компилятора: как вы можете видеть, общие параметры не являются контрвариантными. Поэтому, когда вы переносите ссылку параметра на WeakReference<T>
, T
должен точно соответствовать типу этого параметра.
Даже если вы не используете __makeref
, вы могли бы понять, что внутреннее поведение CLR - такая вещь.
Кроме того, ссылки более низкого уровня представляют собой структуры, содержащие тип значения и само значение. Таким образом, если вы можете привести ссылку на любой из ее супертипов, вы измените тип ссылки, и когда вы попытаетесь получить ее значение, произойдет сбой, потому что тип значения отличается в зависимости от типа ссылки, к которой он относится. в.