我正在开发一个查看器,它将能够打开我们通过软件生成的所有自定义文档。所有文档都继承自 IDocument,但我不确定如何进行反序列化(以一种好的方式 - 嵌套的 try/catch 可能会起作用,但那将是可怕的)。
所以我的方法现在看起来像这样:
public Boolean OpenDocument(String filename, Type docType, out IDocument document)
{
// exception handling etc. removed for brevity
FileStream fs = null;
BinaryFormatter bFormatter = new BinaryFormatter();
fs = new FileStream(filename, FileMode.Open);
document = (docType)bFormatter.Deserialize(fs);
return true;
}
显然这不起作用,因为我不能那样使用变量 docType,但我认为它说明了我正在尝试做的事情的要点。解决这个问题的正确方法是什么?
编辑> @John 好吧,也许我应该追加另一个问题: 如果我有一个接口(interface):
public interface IDocument
{
public Int32 MyInt { get; }
}
和一个类:
public class SomeDocType : IDocument
{
protected Int32 myInt = 0;
public Int32 MyInt { get { return myint; } }
public Int32 DerivedOnlyInt;
}
如果我反序列化为 IDocument,DerivedOnlyInt 是否会成为对象的一部分 - 这样在反序列化之后,我可以转换为 SomeDocType 就没问题了吗?
最佳答案
为什么不直接转换为 IDocument
?您认为强制转换为确切类型在这里有什么好处?
如果您希望调用者以强类型方式获得结果,我会使用泛型来编写它:
public T OpenDocument<T>(String filename) where T : IDocument
{
using (FileStream fs = new FileStream(filename, FileMode.Open))
{
BinaryFormatter bFormatter = new BinaryFormatter();
return (T) bFormatter.Deserialize(fs);
}
}
当然,这取决于调用者在编译时知道正确的类型。如果他们不这样做,无论如何他们都不会知道如何使用正确的类型,所以只需返回 IDocument
:
public IDocument OpenDocument(String filename)
{
using (FileStream fs = new FileStream(filename, FileMode.Open))
{
BinaryFormatter bFormatter = new BinaryFormatter();
return (IDocument) bFormatter.Deserialize(fs);
}
}
编辑:要回答对您问题的编辑,是的,派生属性仍然存在。转换实际上并没有改变一个对象——它只是意味着你得到了一个编译器知道是合适类型的引用。
关于c# - 在运行时转换为多个(未知类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/619197/