Возможно, название не лучшее описание.Как писать в Xml с использованием производных классов?
Моя ситуация в зависимости от интерфейса Я хочу написать одно из его свойств, которое является объектом. Пожалуйста, посмотрите на следующий пример:
public interface IFoo
{
// anothers properties...
object Value { get; }
}
И у меня есть три реализаций этого здесь, убедитесь, что стоимость может быть скрыт истинный тип данных.
public class FooA : IFoo
{
public string Value { get; set; }
object IFoo.Value { get { return Value; } }
}
public class FooB : IFoo
{
public int Value { get; set; }
object IFoo.Value { get { return Value; } }
}
public class FooC : IFoo
{
public List<double> Value { get; set; }
object IFoo.Value { get { return Value; } }
}
В моем сценарии очень важно не использовать дженерики. Поэтому с этой реализацией мне нужно написать в Xml только значение Value.
Например:
static void Main(string[] args)
{
List<IFoo> fooList = new List<IFoo>()
{
new FooA() { Value = "String" },
new FooB() { Value = 2 },
new FooC() { Value = new List<double>() {2, 3.4 } }
};
// Write in a Xml the elements of this list with the property Value (and the problem is the datartype,
// strings, ints, lists, etc)
// ...
}
Я думал, используя XmlSerialization, но я не хочу, чтобы хранить все свойства объекта, только значение свойства.
Мне нужен способ написать свойство Value (не хранить все свойства этого интерфейса) и способ узнать, какую реализацию IFoo я использую.
UPDATE: Я хочу иметь XML-файл, подобный этому.
<Foos>
<Foo xsi:Type="FooA" Value="String" />
<Foo xsi:Type="FooB" Value="2" />
<Foo xsi:Type="FooC" >
<Value>
<List xsi:Type="Double">
<Element>2</Element>
<Element>3.4</Element>
</List>
</Value>
</Foo
</Foos>
Это всего лишь идея. Идея состоит в том, чтобы сохранить только свойство IFoo и возможность получить конкретный объект со значением.
UPDATE:
Благодаря Раджа Nagalingam, чтобы помочь мне с этой идеей. Это то, что я сделал.
public interface IFoo
{
object Value { get; }
}
public abstract class Foo<T> : IFoo, IXmlSerializable
{
[XmlElement]
public T Value { get; set; }
[XmlIgnore]
object IFoo.Value { get { return Value; } }
XmlSchema IXmlSerializable.GetSchema() { return null; }
void IXmlSerializable.ReadXml(XmlReader reader) { throw new NotImplementedException(); }
void IXmlSerializable.WriteXml(XmlWriter writer)
{
XmlSerializer serial = new XmlSerializer(Value.GetType());
serial.Serialize(writer, Value);
}
}
public class FooA : Foo<string> { }
public class FooB : Foo<int> { }
public class FooC : Foo<List<Double>> { }
public class FooContainer : List<IFoo>, IXmlSerializable
{
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader) { throw new NotImplementedException(); }
public void WriteXml(XmlWriter writer)
{
ForEach(x =>
{
XmlSerializer serial = new XmlSerializer(x.GetType());
serial.Serialize(writer, x);
});
}
}
class Program
{
static void Main(string[] args)
{
FooContainer fooList = new FooContainer()
{
new FooA() { Value = "String" },
new FooB() { Value = 2 },
new FooC() { Value = new List<double>() {2, 3.4 } }
};
XmlSerializer serializer = new XmlSerializer(fooList.GetType(),
new Type[] { typeof(FooA), typeof(FooB), typeof(FooC) });
System.IO.TextWriter textWriter = new System.IO.StreamWriter(@"C:\temp\demo.xml");
serializer.Serialize(textWriter, fooList);
textWriter.Close();
}
}
И это работает, но я предполагаю, что это невозможно восстановить список с конкретными классами, используя стандартную сериализацию я вижу, что она написана с использованием XSI, и на этот раз я не могу их видеть. Как восстановить мои объекты?
Кажется, что все в порядке с решением. Я планирую создать сотни модулей, таких как Foo, поэтому многие из них могут содержать повторяющийся тип данных. Как вы думаете, это единственный способ сделать это? Поскольку каждый модуль, который я реализую, должен иметь IXmlSerialization –
Да, это единственный способ настроить сериализацию ваших классов XML так, как вам нужно. Если вы не заботитесь о выходе XML, вы можете также использовать стандартную сериализацию, предоставляемую .NET. – RajN
Как вы думаете, можно использовать стандартную сериализацию, например [XmlElement] в свойстве Value. У меня проблемы, потому что я пытался сериализовать интерфейс –