Я адаптирую существующую библиотеку классов .NET к переносимой библиотеке классов. Я использую профиль 78 (.NET 4.5, Windows Store 8, Windows Phone 8) в пользу профиля 158 (который также нацелен на Silverlight 5), потому что я хочу иметь возможность компилировать код unsafe
исходной библиотеки.
В библиотеке .NET содержится довольно много классов с пометкой [Serializable]
, поэтому я внедрил библиотеку поддержки PCL, содержащую реалистичную реализацию SerializableAttribute
:
public class SerializableAttribute : Attribute { }
на который ссылается основная библиотека PCL.
Чтобы достаточно использовать основную библиотеку PCL в .NET-приложении, избегая конфликтов имен типов, я также подготовил библиотеку поддержки .NET(с тем же именем, что и библиотека поддержки PCL), содержащую объявление пересылки типов:
[assembly: TypeForwardedTo(SerializableAttribute)]
и в моем приложении .NET явно ссылаются на библиотеку поддержки .NET вместо PCL.
После того, как вы подготовили все это и смогли успешно скомпилировать библиотеку, адаптированную к PCL, я повторно использую модульные тесты из исходной библиотеки .NET, теперь ссылаясь на основную библиотеку PCL и библиотеку поддержки .NET.
Это обычно работает очень хорошо, но для модульных тестов, которые включают класс [Serializable]
с [OnDeserialized]
оформленным способом:
[Serializable]
public class Foo
{
[OnDeserialized]
private void DoSomething(StreamingContext context) { }
}
Я получаю следующее TypeLoadException
:
Тип 'Foo' в сборке 'MyPclAssembly' имеет метод DoSomething с неправильной сигнатурой для атрибута сериализации, который он украшен.
(Можно отметить, что OnDeserializedAttribute
включен в переносное подмножество, предположительно потому, что он также распознается в сериализации [DataContract]
.)
Я не получаю исключение при выполнении модульных тестов в исходной библиотеке .NET. Я тщательно проанализировал подпись метода в классе Foo
и полностью согласуется с сигнатурой, которую должны иметь эти вспомогательные методы сериализации (см. здесь. Я также попытался изменить видимость метода [OnDeserialized]
на internal
и public
, но безрезультатно.
В чем причина этого исключения при использовании библиотеки PCL и что я могу сделать, чтобы избежать этого?
EDIT Я изучил IL-код библиотеки PCL и библиотеки .NET для метода [OnDeserialized]
, и я не вижу никакой существенной разницы:
PCL
.method private hidebysig instance void DoSomething(valuetype [System.Runtime.Serialization.Primitives]System.Runtime.Serialization.StreamingContext context) cil managed
.NET
.method private hidebysig instance void DoSomething(valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed
Ссылки на сборку для StreamingContext
различны, но я предполагаю, что сборка PCL System.Runtime.Serialization.Primitives - это просто переадресация типа к типам mscorlib?
В настоящее время я решил исключить методы [OnDeserialized]
из моего проекта PCL, так как я вообще не планирую использовать сериализацию. Ответ на то, почему я испытываю TypeLoadException
, по-прежнему приветствуется.