Дилемма с классами XSD, Generics и C#
У меня есть следующий простой файл XSD:
<xs:element name="Search" type="SearchObject"/>
<xs:complexType name="SearchObject">
<xs:choice>
<xs:element name="Simple" type="SimpleSearch"/>
<xs:element name="Extended" type="ExtendedSearch"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="SimpleSearch">
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ExtendedSearch">
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Age" type="xs:int"/>
<xs:element name="Address" type="xs:string"/>
</xs:sequence>
</xs:complexType>
Я использую Visual Studio Shell следующим образом:
xsd XMLSchema.xsd /c
В основном /c означает генерацию классов C# из XMLSchema.xsd.
Затем классы выглядят примерно так:
[System.Xml.Serialization.XmlRootAttribute("Search", Namespace="http://tempuri.org/XMLSchema.xsd", IsNullable=false)]
public partial class SearchObject {
private object itemField;
[System.Xml.Serialization.XmlElementAttribute("Extended", typeof(ExtendedSearch))]
[System.Xml.Serialization.XmlElementAttribute("Simple", typeof(SimpleSearch))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
}
Мой первый вопрос: почему свойство "Элемент" не называется "Поиск", как я установил в файле xsd для этого элемента?
Мой второй вопрос: почему свойство Item объекта типа? Я установил выбор внутри моего xsd-файла и хотел бы, чтобы код на C# выглядел так:
public partial class SearchObject<T> where T : SimpleSearch, where T : ExtendedSearch
{
public T Search
{
get ...
set ...
}
}
Я хотел бы иметь какой-то универсальный класс, который позволяет только те типы, которые я указал в блоке выбора в файле xsd, которые в моем случае SimpleSearch и ExtendedSearch.
Это вообще возможно, и если да, то как я могу сделать это правильно?
1 ответ
Выбор в xsd означает, что вы можете иметь один из объявленных типов объектов. И поэтому xsd.exe генерирует объект (всегда с именем Item) вместо строгого типа. См. http://msdn.microsoft.com/en-us/library/sa6z5baz(v=vs.85).aspx. Вы должны проверить во время выполнения, какой тип объекта:
ExtendedSearch extendedSearch = null;
SimpleSearch simpleSearch = null;
if(Item is ExtendedSearch)
extendedSearch = (ExtendedSearch)Item;
else if(Item is SimpleSearch)
simpleSearch = (SimpleSearch)Item;