我有一個對象,我需要爲了轉移至高性能計算集羣用於以後使用
此前序列化,我使用的出我的對象代表一個統計形狀模型,並且所有人都愉快地工作了。我的對象變得更加複雜了,我決定通過實現ISerializable定製序列化過程。我繼續支持存儲在先前格式的數據
的問題
我的問題是一個具體值似乎成功序列化,但始終都是空值,當我試圖反序列化。 (沒有錯誤,只是一個非常不愉快的,無用的null)
當我在序列化的時候斷開,我可以看到對象被添加到SerializationInfo ok通過檢查SerializationInfo並且它有值(它是沒有什麼奇特的,但會發佈下面的代碼)
序列化構造函數正在調用(我也放了一個斷點),但是當我檢查構造函數的SerializationInfo對象時,它沒有數據(它沒有數據)
UPDATE - download console app here。感謝您尋找
,或者看代碼在這裏:
守則
類引起的問題:(該PointProfiles屬性是有問題的對象)
[Serializable]
public class TrainingSet : ITrainingSet, ISerializable
{
public Dictionary<Tuple<int, int>, IPointTrainingSet> PointProfiles { get; set; }
public PrincipalComponentAnalysis PointPCA { get; set; }
public double[] AlignedMean { get; set; }
public List<Tuple<string, ITransform>> Transforms { get; set; }
public string[] FileNames { get; set; }
private static Lazy<BinaryFormatter> formatter = new Lazy<BinaryFormatter>();
public static ITrainingSet Load(Guid modelId)
{
ModelSample s = DataProxy<ModelSample>.AsQueryable().Where(m => m.ModelId == modelId).SingleOrDefault();
if (s == null)
return null;
byte[] raw = s.Samples.ToArray();
using (MemoryStream ms = new MemoryStream(raw))
return (ITrainingSet)formatter.Value.Deserialize(ms);
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("pca", PointPCA);
info.AddValue("tp1", PointProfiles.Select(pp => pp.Key.Item1).ToArray());
info.AddValue("tp2", PointProfiles.Select(pp => pp.Key.Item2).ToArray());
var x = PointProfiles.Select(pp => (ProfileModel)pp.Value).ToArray();
info.AddValue("ipts", x, typeof(ProfileModel[]));
info.AddValue("am", AlignedMean);
info.AddValue("tname", Transforms.Select(t => t.Item1).ToArray());
info.AddValue("tval", Transforms.Select(t => t.Item2).ToArray());
info.AddValue("fnames", FileNames);
info.AddValue("version", 1); // nb
}
public TrainingSet(SerializationInfo info, StreamingContext context)
{
int version = 0;
foreach(SerializationEntry s in info)
{
if(s.Name == "version")
version = (int)s.Value;
}
switch(version)
{
case 0:
// old (default binary formatter)
PointPCA = info.GetValue("<PointPCA>k__BackingField", typeof(PrincipalComponentAnalysis)) as PrincipalComponentAnalysis;
PointProfiles = info.GetValue("<PointProfiles>k__BackingField", typeof(Dictionary<Tuple<int, int>, IPointTrainingSet>)) as Dictionary<Tuple<int, int>, IPointTrainingSet>;
AlignedMean = info.GetValue("<AlignedMean>k__BackingField", typeof(double[])) as double[];
Transforms = info.GetValue("<Transforms>k__BackingField", typeof(List<Tuple<string, ITransform>>)) as List<Tuple<string, ITransform>>;
FileNames = info.GetValue("<FileNames>k__BackingField", typeof(string[])) as string[];
//stats.PointPCA = pointPCA;
//stats.PointProfiles = pointProfiles;
//stats.AlignedMean = alignedMean;
//stats.Transforms = transforms;
//stats.FileNames = fileNames;
break;
case 1:
FileNames = info.GetValue("fnames", typeof(string[])) as string[];
var t = info.GetValue("tval", typeof(ITransform[])) as ITransform[];
var tn = info.GetValue("tname", typeof(string[])) as string[];
Transforms = new List<Tuple<string, ITransform>>();
for(int i = 0;i < tn.Length;i++)
Transforms.Add(new Tuple<string,ITransform>(tn[i], t[i]));
AlignedMean = info.GetValue("am", typeof(double[])) as double[];
PointPCA = info.GetValue("pca", typeof(PrincipalComponentAnalysis)) as PrincipalComponentAnalysis;
var ipts = info.GetValue("ipts", typeof(ProfileModel[]));
foreach (var x in info)
{
int a = 0;
a++; // break point here, info has an entry for key "ipts", but it's null (or rather an array of the correct length, and each element of the array is null)
}
var xxx = ipts as IPointTrainingSet[];
var i2 = info.GetValue("tp2", typeof(int[])) as int[];
var i1 = info.GetValue("tp1", typeof(int[])) as int[];
PointProfiles = new Dictionary<Tuple<int, int>, IPointTrainingSet>();
for (int i = 0; i < i1.Length; i++)
PointProfiles.Add(new Tuple<int, int>(i1[i], i2[i]), xxx[i]);
break;
default:
throw new NotImplementedException("TrainingSet version " + version + " is not supported");
}
}
public TrainingSet()
{
}
}
Profile類(也可序列化的,這是接下來列出的ProfileModel的基類)
[Serializable]
public class Profile : ISerializable, IProfile
{
public double Angle { get; private set; }
public int PointIndex { get; private set; }
public int Level { get; set; }
public double[,] G { get; private set; }
public virtual double[,] GBar { get { throw new InvalidOperationException(); } }
public virtual int Width { get { return G.Length; } }
public Profile(int level, int pointIndex, double angle, double[,] G)
{
this.G = G;
PointIndex = pointIndex;
Level = level;
Angle = angle;
}
// deserialization
public Profile(SerializationInfo info, StreamingContext context)
{
PointIndex = info.GetInt32("p");
Angle = info.GetDouble("a");
G = (double[,])info.GetValue("g", typeof(double[,]));
Level = info.GetInt32("l");
//_pca = new Lazy<PrincipalComponentAnalysis>(Pca);
}
// serialization
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("p", PointIndex);
info.AddValue("a", Angle);
info.AddValue("g", G);
info.AddValue("l", Level);
}
}
和(最後)的ProfileModel類:
[Serializable]
public class ProfileModel : Profile, ISerializable, IPointTrainingSet
{
public IProfile MeanProfile { get; private set; }
private ProfileModel(int level, int PointIndex, IProfile[] profiles)
: base(level, PointIndex, 0, null)
{
double[,] m = Matrix.Create<double>(profiles.Length, profiles[0].G.Columns(), 0);
int idx = 0;
foreach (var pg in profiles.Select(p => p.G.GetRow(0)))
m.SetRow(idx++, pg);
Profile meanProfile = new Profile(level, PointIndex, 0, m.Mean().ToMatrix());
MeanProfile = meanProfile;
}
// deserialization
public ProfileModel(SerializationInfo info, StreamingContext context) : base(info, context) {
var ps = info.GetValue("mp", typeof(Profile));
MeanProfile = (IProfile)ps;
}
// serialization
public new void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("mp", MeanProfile, typeof(Profile));
base.GetObjectData(info, context);
}
public override double[,] GBar
{
get
{
return MeanProfile.G;
}
}
public override int Width { get {
return GBar.Columns();
} }
}
如果你能發現任何東西,我做錯了,可能導致這種情況發生,我會非常非常感謝:)
也許它與那個'Tuple'有關? [http://stackoverflow.com/questions/13739348/why-i-could-not-serialize-a-tuple-in-c](http://stackoverflow.com/questions/13739348/why-i-could- not-serialize-a-tuple-in-c) –
Rohrbs
@Rohrbs - 感謝您的看法:)我確實在想 - 這就是爲什麼元組和字典都是以定製的,單獨的方式序列化的(請參閱名爲「tp1 「和」tp2「 - 」ipts「是字典的第三部分) – Nathan
對不起,在仔細觀察後,沒有什麼會跳出來對我說。也許這裏演員'pp =>(int)pp.Key.Item1'?哪些值回到空值? tp1,tp2還是ipts?三個全部? – Rohrbs