2016-02-11 2 views
0

Я заметил, что анонимные типы помещаются в стандартные объекты, когда они передаются между потоками.. Анонимные типы .NET, измененные на стандартные объекты

Почему? Я читал, что они должны быть местными.

+2

Любое значение должно быть преобразовано в * объект *, когда вы передаете его целевому методу ThreadStart. И все они могут, очень простая гарантия времени исполнения. Анонимный тип не является особым типом, он просто не имеет имени в вашей программе. Поэтому отбрасывание его из аргумента * object * будет немного разочаровывающим. Вы можете наложить его на * dynamic * и позволить DLR понять это. «Предположительно, чтобы быть локальным», конечно, хороший совет, особенно когда многопоточный код живет в другой сборке. Только не надо. –

+1

Анонимные типы ** являются ** стандартными типами. У них просто нет имени. Это простые старые стандартные объекты типа стандартного .NET. Если я 'GetType()' на одном, который я только что создал, я получаю это 'FullName':' <> f__AnonymousType0'2 [[System.Int32, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089], [ System.String, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]] '. Свойством IsClass является 'true' и' IsValueType' является 'false'. – Enigmativity

ответ

1

Анонимные типы : стандартные типы. У них просто нет имени. Это простые старые стандартные объекты типа стандартного .NET. Они не попадают в коробку, когда передаются в качестве параметров.

Если я запускаю этот код:

var x = new { A = 5, B = "Hello" }; 

Console.WriteLine(x.GetType().FullName); 
Console.WriteLine(x.GetType().IsClass); 
Console.WriteLine(x.GetType().IsValueType); 

... Я получаю этот выход:

 
f__AnonymousType0`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 
True 
False 

типы Анонимные классы, а не типы значений, поэтому не в штучной упаковке.

Если вы разъехаться на метод и вы хотите получить его обратно сильно типа анонимный объект, то вы можете сделать это:

public T Rehydrate<T>(object anonymous, T prototype) 
{ 
    return (T)anonymous; 
} 

я могу использовать его как это:

var x = new { A = 5, B = "Hello" }; 

var y = (object)x; 

var z = Rehydrate(x, new { A = 0, B = "" }); 

Console.WriteLine(z.A); 
Console.WriteLine(z.B); 

я получаю следующий результат:

 
5 
Hello 

параметр prototype в Rehydrate должны иметь одинаковые имена свойств, те же типы свойств и в том же порядке, что и параметр anonymous для этого. Если у вас есть обе стороны кода - вызывающий и вызываемый - тогда это не проблема.

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