System.Version未序列化
我有一个带有System.Version
属性的类,如下所示:
当我序列化类时,版本始终为空:
Client类看起来像:
[Serializable] public class Client { public string Description; public string Directory; public DateTime ReleaseDate; public Version Version; }
System.Version
不可序列化,如果你在MSDN上查看它的属性 ,你会发现它们没有setter …所以序列化程序不会存储它们。 但是, 这种方法仍然有效 。 那篇文章(旧的但仍然有效)提供了一个可序列化的Version类,你可以切换到那个并继续吗?
由tomfanning编辑
我已经从archive.org中删除了死网站的代码,转载如下。
using System; using System.Globalization; namespace CubicOrange.Version { /// /// Serializable version of the System.Version class. /// [Serializable] public class ModuleVersion : ICloneable, IComparable { private int major; private int minor; private int build; private int revision; /// /// Gets the major. /// /// public int Major { get { return major; } set { major = value; } } /// /// Gets the minor. /// /// public int Minor { get { return minor; } set { minor = value; } } /// /// Gets the build. /// /// public int Build { get { return build; } set { build = value; } } /// /// Gets the revision. /// /// public int Revision { get { return revision; } set { revision = value; } } /// /// Creates a new instance. /// public ModuleVersion() { this.build = -1; this.revision = -1; this.major = 0; this.minor = 0; } /// /// Creates a new instance. /// /// Version. public ModuleVersion(string version) { this.build = -1; this.revision = -1; if (version == null) { throw new ArgumentNullException("version"); } char[] chArray1 = new char[1] { '.' }; string[] textArray1 = version.Split(chArray1); int num1 = textArray1.Length; if ((num1 < 2) || (num1 > 4)) { throw new ArgumentException("Arg_VersionString"); } this.major = int.Parse(textArray1[0], CultureInfo.InvariantCulture); if (this.major < 0) { throw new ArgumentOutOfRangeException("version", "ArgumentOutOfRange_Version"); } this.minor = int.Parse(textArray1[1], CultureInfo.InvariantCulture); if (this.minor < 0) { throw new ArgumentOutOfRangeException("version", "ArgumentOutOfRange_Version"); } num1 -= 2; if (num1 > 0) { this.build = int.Parse(textArray1[2], CultureInfo.InvariantCulture); if (this.build < 0) { throw new ArgumentOutOfRangeException("build", "ArgumentOutOfRange_Version"); } num1--; if (num1 > 0) { this.revision = int.Parse(textArray1[3], CultureInfo.InvariantCulture); if (this.revision < 0) { throw new ArgumentOutOfRangeException("revision", "ArgumentOutOfRange_Version"); } } } } /// /// Creates a new instance. /// /// Major. /// Minor. public ModuleVersion(int major, int minor) { this.build = -1; this.revision = -1; if (major < 0) { throw new ArgumentOutOfRangeException("major", "ArgumentOutOfRange_Version"); } if (minor < 0) { throw new ArgumentOutOfRangeException("minor", "ArgumentOutOfRange_Version"); } this.major = major; this.minor = minor; this.major = major; } /// /// Creates a new instance. /// /// Major. /// Minor. /// Build. public ModuleVersion(int major, int minor, int build) { this.build = -1; this.revision = -1; if (major < 0) { throw new ArgumentOutOfRangeException("major", "ArgumentOutOfRange_Version"); } if (minor < 0) { throw new ArgumentOutOfRangeException("minor", "ArgumentOutOfRange_Version"); } if (build < 0) { throw new ArgumentOutOfRangeException("build", "ArgumentOutOfRange_Version"); } this.major = major; this.minor = minor; this.build = build; } /// /// Creates a new instance. /// /// Major. /// Minor. /// Build. /// Revision. public ModuleVersion(int major, int minor, int build, int revision) { this.build = -1; this.revision = -1; if (major < 0) { throw new ArgumentOutOfRangeException("major", "ArgumentOutOfRange_Version"); } if (minor < 0) { throw new ArgumentOutOfRangeException("minor", "ArgumentOutOfRange_Version"); } if (build < 0) { throw new ArgumentOutOfRangeException("build", "ArgumentOutOfRange_Version"); } if (revision < 0) { throw new ArgumentOutOfRangeException("revision", "ArgumentOutOfRange_Version"); } this.major = major; this.minor = minor; this.build = build; this.revision = revision; } #region ICloneable Members /// /// Clones this instance. /// /// public object Clone() { ModuleVersion version1 = new ModuleVersion(); version1.major = this.major; version1.minor = this.minor; version1.build = this.build; version1.revision = this.revision; return version1; } #endregion #region IComparable Members /// /// Compares to. /// /// Obj. /// public int CompareTo(object version) { if (version == null) { return 1; } if (!(version is ModuleVersion)) { throw new ArgumentException("Arg_MustBeVersion"); } ModuleVersion version1 = (ModuleVersion)version; if (this.major != version1.Major) { if (this.major > version1.Major) { return 1; } return -1; } if (this.minor != version1.Minor) { if (this.minor > version1.Minor) { return 1; } return -1; } if (this.build != version1.Build) { if (this.build > version1.Build) { return 1; } return -1; } if (this.revision == version1.Revision) { return 0; } if (this.revision > version1.Revision) { return 1; } return -1; } #endregion /// /// Equalss the specified obj. /// /// Obj. /// public override bool Equals(object obj) { if ((obj == null) || !(obj is ModuleVersion)) { return false; } ModuleVersion version1 = (ModuleVersion)obj; if (((this.major == version1.Major) && (this.minor == version1.Minor)) && (this.build == version1.Build) && (this.revision == version1.Revision)) { return true; } return false; } /// /// Gets the hash code. /// /// public override int GetHashCode() { int num1 = 0; num1 |= ((this.major & 15) << 0x1c); num1 |= ((this.minor & 0xff) << 20); num1 |= ((this.build & 0xff) << 12); return (num1 | this.revision & 0xfff); } /// /// Operator ==s the specified v1. /// /// V1. /// V2. /// public static bool operator ==(ModuleVersion v1, ModuleVersion v2) { return v1.Equals(v2); } /// /// Operator >s the specified v1. /// /// V1. /// V2. /// public static bool operator >(ModuleVersion v1, ModuleVersion v2) { return (v2 < v1); } /// /// Operator >=s the specified v1. /// /// V1. /// V2. /// public static bool operator >=(ModuleVersion v1, ModuleVersion v2) { return (v2 <= v1); } /// /// Operator !=s the specified v1. /// /// V1. /// V2. /// public static bool operator !=(ModuleVersion v1, ModuleVersion v2) { return (v1 != v2); } /// /// Operator <s the specified v1. /// /// V1. /// V2. /// public static bool operator <(ModuleVersion v1, ModuleVersion v2) { if (v1 == null) { throw new ArgumentNullException("v1"); } return (v1.CompareTo(v2) < 0); } /// /// Operator <=s the specified v1. /// /// V1. /// V2. /// public static bool operator <=(ModuleVersion v1, ModuleVersion v2) { if (v1 == null) { throw new ArgumentNullException("v1"); } return (v1.CompareTo(v2) <= 0); } /// /// Toes the string. /// /// public override string ToString() { if (this.build == -1) { return this.ToString(2); } if (this.revision == -1) { return this.ToString(3); } return this.ToString(4); } /// /// Toes the string. /// /// Field count. /// public string ToString(int fieldCount) { object[] objArray1; switch (fieldCount) { case 0: { return string.Empty; } case 1: { return (this.major.ToString()); } case 2: { return (this.major.ToString() + "." + this.minor.ToString()); } } if (this.build == -1) { throw new ArgumentException(string.Format("ArgumentOutOfRange_Bounds_Lower_Upper {0},{1}", "0", "2"), "fieldCount"); } if (fieldCount == 3) { objArray1 = new object[5] { this.major, ".", this.minor, ".", this.build }; return string.Concat(objArray1); } if (this.revision == -1) { throw new ArgumentException(string.Format("ArgumentOutOfRange_Bounds_Lower_Upper {0},{1}", "0", "3"), "fieldCount"); } if (fieldCount == 4) { objArray1 = new object[7] { this.major, ".", this.minor, ".", this.build, ".", this.revision }; return string.Concat(objArray1); } throw new ArgumentException(string.Format("ArgumentOutOfRange_Bounds_Lower_Upper {0},{1}", "0", "4"), "fieldCount"); } } }
我更喜欢使用下面的方法,所以我的类中只有一个类型为VersionXml的属性。 隐式运算符在这里非常有用。
[Serializable] [XmlType("Version")] public class VersionXml { public VersionXml() { this.Version = null; } public VersionXml(Version Version) { this.Version = Version; } [XmlIgnore] public Version Version { get; set; } [XmlText] [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] public string Value { get { return this.Version == null ? string.Empty : this.Version.ToString(); } set { Version temp; Version.TryParse(value, out temp); this.Version = temp; } } public static implicit operator Version(VersionXml VersionXml) { return VersionXml.Version; } public static implicit operator VersionXml(Version Version) { return new VersionXml(Version); } public override string ToString() { return this.Value; } }
您可以使用字符串代理属性:
[XmlIgnore] public System.Version Version { get; set; } [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] public string version { get { if (this.Version == null) return string.Empty; else return this.Version.ToString(); } set { if(!String.IsNullOrEmpty(value)) this.Version = new Version(value); } }
您需要定义get
和set
访问器,如下所示:
public class Version { public int Build { get; set; } public int Major { get; set; } public int MajorRevision { get; set; } public int Minor { get; set; } public int MinorRevision { get; set; } public int Revision { get; set; } } // ... new XmlSerializer(typeof (Version)) .Serialize(Console.Out, new Version() { Build = 111, Major = 1, MajorRevision = 0, Minor = 1, MinorRevision = 10, Revision = 10 } );
我得到了这个输出:
111 1 0 1 10 10
更准确地说, System.Version
不是XML可序列化的。 它可以使用BinaryFormatter
进行序列化,例如:
Version version = new Version(1, 2, 3, 4); using (MemoryStream stream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, version); stream.Position = 0; Version deserialized = (Version)formatter.Deserialize(stream); }
我已经清理了Nick Craver的实现更加简洁和可读,添加了XML Serialization支持(使用属性而不是单独的元素),实现了字符串TypeConverter以及修复了一些可能存在NullReferenceExceptions或无限循环的比较问题(从内部调用重载的运算符)。
我也使用了一些C#6function。
上述就是C#学习教程:System.Version未序列化分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Xml.Serialization; [Serializable] [TypeConverter(typeof(VersionCodeConverter))] public class VersionCode : ICloneable, IComparable, IEquatable { [XmlAttribute] public int Major { get; private set; } [XmlAttribute] public int Minor { get; private set; } [XmlAttribute] public int Build { get; private set; } = -1; [XmlAttribute] public int Revision { get; private set; } = -1; public VersionCode() { } public VersionCode(int major, int minor, int build = 0, int revision = 0) { if (major < 0) throw new ArgumentOutOfRangeException(nameof(major), $"{nameof(major)} cannot be less than 0"); if (minor < 0) throw new ArgumentOutOfRangeException(nameof(minor), $"{nameof(minor)} cannot be less than 0"); if (build < 0) throw new ArgumentOutOfRangeException(nameof(build), $"{nameof(build)} cannot be less than 0"); if (revision < 0) throw new ArgumentOutOfRangeException(nameof(revision), $"{nameof(revision)} cannot be less than 0"); Major = major; Minor = minor; Build = build; Revision = revision; } public VersionCode(string version) { if (version == null) throw new ArgumentNullException(nameof(version)); var components = new Stack(version.Split('.')); if (components.Count < 2 || components.Count > 4) throw new ArgumentException(nameof(version)); Major = int.Parse(components.Pop(), CultureInfo.InvariantCulture); if (Major < 0) throw new ArgumentOutOfRangeException(nameof(version), $"{nameof(Major)} cannot be less than 0"); Minor = int.Parse(components.Pop(), CultureInfo.InvariantCulture); if (Minor < 0) throw new ArgumentOutOfRangeException(nameof(version), $"{nameof(Minor)} cannot be less than 0"); if (!components.Any()) return; Build = int.Parse(components.Pop(), CultureInfo.InvariantCulture); if (Build < 0) throw new ArgumentOutOfRangeException(nameof(version), $"{nameof(Build)} cannot be less than 0"); if (!components.Any()) return; Revision = int.Parse(components.Pop(), CultureInfo.InvariantCulture); if (Revision < 0) throw new ArgumentOutOfRangeException(nameof(version), $"{nameof(Revision)} cannot be less than 0"); } public object Clone() => new VersionCode(Major, Minor, Build, Revision); public int CompareTo(VersionCode version) => Major != version.Major ? Major.CompareTo(version.Major) : Minor != version.Minor ? Minor.CompareTo(version.Minor) : Build != version.Build ? Build.CompareTo(version.Build) : Revision.CompareTo(version.Revision); public override bool Equals(object obj) => obj is VersionCode && Equals((VersionCode)obj); public bool Equals(VersionCode version) => Major == version.Major && Minor == version.Minor && Build == version.Build && Revision == version.Revision; public override int GetHashCode() { var hash = 0; hash |= (Major & 15) << 0x1c; hash |= (Minor & 0xff) << 20; hash |= (Build & 0xff) << 12; hash |= (Revision & 0xfff); return hash; } public static bool operator ==(VersionCode v1, VersionCode v2) => ReferenceEquals(v1, null) ? ReferenceEquals(v2, null) : v1.Equals(v2); public static bool operator !=(VersionCode v1, VersionCode v2) => !(v1 == v2); public static bool operator >(VersionCode v1, VersionCode v2) => v2 < v1; public static bool operator >=(VersionCode v1, VersionCode v2) => v2 <= v1; public static bool operator <(VersionCode v1, VersionCode v2) => !ReferenceEquals(v1, null) && v1.CompareTo(v2) < 0; public static bool operator <=(VersionCode v1, VersionCode v2) => !ReferenceEquals(v1, null) && v1.CompareTo(v2) <= 0; public override string ToString() => Build < 0 ? $"{Major}.{Minor}" : Revision < 0 ? $"{Major}.{Minor}.{Build}" : $"{Major}.{Minor}.{Build}.{Revision}"; } public class VersionCodeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) => sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { var version = value as string; return version != null ? new VersionCode(version) : base.ConvertFrom(context, culture, value); } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1015918.html