如何使用参数化构造函数实现保存/加载接口?

时间:2011-04-04 15:12:03

标签: c# serialization constructor

我知道接口不能定义构造函数。这就是我希望我能做到的:

public interface SavableObject {
    void Save(ObjectSaver saver);
    SavableObject(ObjectLoader loader); //This, obviously, doesn't work
}


//Loading an object inside ObjectLoader:
T LoadObject<T>() where T : SavableObject  {
    return (T)Activator.CreateInstance(typeof(T), this);
}

如果我拿出不起作用的行,我就可以做到这一点,并且当尝试加载(或者可能保存,如果我在其中放置一个断言)时,如果它没有那么就会出现运行时错误没有构造函数。我只是想知道是否有任何方法要求类具有可以与Activator一起使用的特定构造函数。我可以以某种方式使用自定义属性,并要求该属性在类上吗?或者我必须依靠运行时检查来加载和保存数据吗?

我知道我可以使用无参数构造函数和Load(ObjectLoader)方法,但我不一定希望将无参数构造函数用于其他目的。

6 个答案:

答案 0 :(得分:1)

ISerializable怎么办?

答案 1 :(得分:0)

简而言之,我建议您像大多数工厂一样使用generics

public interface SavableObject<T> : where T : new
{
    void Save(IObjectSaver<T> saver);
    SavableObject<T> Load(ObjectLoader loader); //This, obviously, doesn't work
}

然而,你好像已经把它转过来了。 班级正在做工厂必须做的事情。所以我认为将工厂传递给实体本身不是一个好主意,这是你在实验中遇到的问题的一部分。设计。

答案 2 :(得分:0)

如果你不害怕使用反射,比如你所展示的激活器,你可以做一些我倾向于使用的技巧:

  1. 制作受保护的无参数构造函数
  2. Make Load方法,也受保护(或私有,我倾向于使用虚拟保护,所以我支持继承)
  3. 使用此非公共构造函数创建新对象(通过反射 - 您无法创建类的实例“就像”使用新运算符“
  4. 调用加载方法(也使用反射 - 以后没有人会调用它)。
  5. 我不知道这对你是否有用,但是当我需要反序列化相当大的游戏状态并且速度非常快时,我使用了这种方法,尽管所有这些反映都是如此(出于很多原因我不想使用内置-in序列化方法和工厂模式不会这样做,所以我倾向于将此方法视为可能有用的东西,如果其他方法失败,另一方面,如果我可以 - 我可能会使用内置序列化以简化)

答案 3 :(得分:0)

如何在界面上添加属性:

public interface SavableObject 
{
    void Save(ObjectSaver saver);
    ObjectLoader ObjectLoader {get; set;}
}

然后在你的工厂:

T LoadObject<T>() where T : SavableObject  
{
    var result = (T)Activator.CreateInstance(typeof(T));
    result.ObjectLoader = this;
    return result;
}

答案 4 :(得分:0)

根据您的问题和意见。

我认为你应该在运行时使用反射来做。

组合构造函数和接口从它的核心是不合逻辑的。接口是关于具体实例可以做什么,而不是如何初始化它。这只能使用抽象类来实现。

也许使用工厂来创建类的实例?

此外,我认为您无法获得比默认ISerializable实施更快的速度。除非你是.NET GURU并且有多年的时间。

答案 5 :(得分:0)

简短的回答:我猜,这是不可能的。我没有可用于在类上要求特定类型的构造函数的属性或概括。