Csharp/C#教程:System.Version未序列化分享


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); } } 

您需要定义getset访问器,如下所示:

 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

(0)
上一篇 2021年12月31日
下一篇 2021年12月31日

精彩推荐