Всего несколько мыслей, авеню или два для исследования.
это возможный иметь функцию, выполняемую каждые 10 секунд и иметь ту проверку "встречная" переменная? Если это возможно, Вы можете иметь на наведении мыши для страницы, можете Вы нет? Если так, используйте событие mouseOver для сброса "встречной" переменной. Если Ваша функция вызвана, и счетчик выше диапазона, который Вы предопределяете, то сделайте свое действие.
Снова, просто некоторые мысли... Надежда это помогает.
Это просто внутреннее ограничение декларативной сериализации, когда информация о типе не встроена в вывод.
При попытке преобразовать
обратно в
public class Flibble { public object Foo { get; set; } }
Как сериализатор узнает, должно ли это быть int, string, double (или что-то еще) ...
Для выполнения этой работы у вас есть несколько вариантов, но если вы действительно не знаете до времени выполнения, самый простой способ сделать это, вероятно, будет использовать XmlAttributeOverrides .
К сожалению, это будет работать только с базовыми классами, но не с интерфейсами. Лучшее, что вы можете сделать, - это игнорировать свойство, которого недостаточно для ваших нужд.
Если вам действительно нужно оставаться с интерфейсами, у вас есть три реальных варианта:
] Уродливый,
Проблемы дублирования усилий аналогичны первому.
public sealed class XmlAnything<T> : IXmlSerializable
{
public XmlAnything() {}
public XmlAnything(T t) { this.Value = t;}
public T Value {get; set;}
public void WriteXml (XmlWriter writer)
{
if (Value == null)
{
writer.WriteAttributeString("type", "null");
return;
}
Type type = this.Value.GetType();
XmlSerializer serializer = new XmlSerializer(type);
writer.WriteAttributeString("type", type.AssemblyQualifiedName);
serializer.Serialize(writer, this.Value);
}
public void ReadXml(XmlReader reader)
{
if(!reader.HasAttributes)
throw new FormatException("expected a type attribute!");
string type = reader.GetAttribute("type");
reader.Read(); // consume the value
if (type == "null")
return;// leave T at default value
XmlSerializer serializer = new XmlSerializer(Type.GetType(type));
this.Value = (T)serializer.Deserialize(reader);
reader.ReadEndElement();
}
public XmlSchema GetSchema() { return(null); }
}
Использование этого потребовало бы чего-то вроде (в проекте P):
public namespace P
{
public interface IFoo {}
public class RealFoo : IFoo { public int X; }
public class OtherFoo : IFoo { public double X; }
public class Flibble
{
public XmlAnything<IFoo> Foo;
}
public static void Main(string[] args)
{
var x = new Flibble();
x.Foo = new XmlAnything<IFoo>(new RealFoo());
var s = new XmlSerializer(typeof(Flibble));
var sw = new StringWriter();
s.Serialize(sw, x);
Console.WriteLine(sw);
}
}
, что дает вам:
<?xml version="1.0" encoding="utf-16"?>
<MainClass
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Foo type="P.RealFoo, P, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<RealFoo>
<X>0</X>
</RealFoo>
</Foo>
</MainClass>
Это, очевидно, более обременительно для пользователей этого класса, хотя и позволяет избежать большого количества шаблонов.
Золотая середина может быть объединением идеи XmlAnything в свойство «поддержки» первой техники. Таким образом, большая часть ворчливой работы выполняется за вас, но потребители этого класса не пострадают, кроме путаницы с самоанализом.
Замена интерфейса IModelObject с абстрактным или конкретным типом и использовать наследование с XMLInclude возможно, но это кажется уродливым обходным путем.
Если возможно использовать абстрактную базу, я бы рекомендовал этот путь. Это все равно будет чище, чем использование сериализации вручную. Единственная проблема, которую я вижу с абстрактной базой, заключается в том, что вам все еще понадобится конкретный тип? По крайней мере, так я использовал его раньше, например:
public abstract class IHaveSomething
{
public abstract string Something { get; set; }
}
public class MySomething : IHaveSomething
{
string _sometext;
public override string Something
{ get { return _sometext; } set { _sometext = value; } }
}
[XmlRoot("abc")]
public class seriaized
{
[XmlElement("item", typeof(MySomething))]
public IHaveSomething data;
}
К сожалению, нет простого ответа, поскольку сериализатор не знает, что сериализовать для интерфейса. Я нашел более полное объяснение того, как это обойти, на MSDN