2009-11-10 7 views
22

Есть ли какие-либо практические применения структуры TypedReference, которую вы действительно используете в реальном коде?Практическое использование TypedReference

EDIT: Структура .Net использует их в перегруженных Console.WriteLine и String.Concat, которые строят массив из __arglist параметра и передают его к нормальной params перегрузке. Почему эти перегрузки существуют?

+1

Почему это неконструктивно? : o – nawfal

+1

Также см. http://stackoverflow.com/questions/4764573/why-is-typedreference-behind-the-scenes-its-so-fast-and-safe-almost-magical – nawfal

+0

Вы также можете использовать его для передачи расположение стека/ссылку на переменные «вокруг» (например, к другому потоку или вернуть его из метода). Для этого требуется небезопасный код и «копирование» TypedReference в виде двух IntPtr. –

ответ

17

Есть ли какие-либо практические применения структуры TypedReference, которые вы фактически использовали бы в реальном коде?

Да. Я бы использовал их, если мне нужна совместимость с вариаторными методами C-стиля.

Почему эти перегрузки существуют?

Они существуют для взаимодействия с абонентами, которые любят использовать вариативные методы C-стиля.

+1

+1 для того, чтобы не хлопать биты варидиана C-стиля :) И вот, надеюсь, у вас будут вариативные шаблоны (а не дженерики) на 5.0. –

10

Это очень старый вопрос, но я хотел бы добавить еще один прецедент: когда у вас есть структура и вы хотите установить ее переменную через отражение, вы всегда будете работать с бокс-значением и никогда измените оригинал. Это бесполезно:

TestFields fields = new TestFields { MaxValue = 1234 }; 
FieldInfo info = typeof(TestFields).GetField("MaxValue"); 
info.SetValue(fields, 4096); 

// result: fields.MaxValue is still 1234!! 

Это может быть исправлено с подразумеваемым боксом, но тогда вы потеряете безопасность типа. Вместо этого вы можете исправить это с помощью TypedParameter:

TestFields fields = new TestFields { MaxValue = 1234 }; 
FieldInfo info = fields.GetType().GetField("MaxValue"); 

TypedReference reference = __makeref(fields); 
info.SetValueDirect(reference, 4096); 

// result: fields.MaxValue is now indeed 4096!! 
+0

Я не знаю, буду ли я называть это конкретной проблемой Reflection. 'SetValue' принимает объект как вход, поэтому любой тип значения будет помещен в бокс для соответствия сигнатуре метода. –

+0

@BrianRasmussen: afaik, это поведение, связанное с отражением, проистекает из дженериков прогнозирования отражения, иначе бокс не понадобится. В (pre-) типы и ссылки со значениями в боксе эта проблема не возникает. – Abel

+0

Моя точка зрения заключалась в том, что любой метод, который принимает «объект» в качестве входного сигнала (который вызывает первую перегрузку «SetValue» в вашем примере), заставит значения быть вложенными. Вот как система унифицированного типа обрабатывает значения. Это не относится к отражению. –

Смежные вопросы