代码之家  ›  专栏  ›  技术社区  ›  MysticEarth

系统。版本未序列化

  •  27
  • MysticEarth  · 技术社区  · 15 年前

    System.Version 属性,如下所示:

    • 版本
      • 建筑:111
      • 专业:1
      • 小调:1
      • 最低视力:10
      • 修订:10

    <Version />
    

    客户端类看起来像:

    [Serializable]
    public class Client
    {
        public string Description;
        public string Directory;
        public DateTime ReleaseDate;
        public Version Version;
    }
    
    6 回复  |  直到 11 年前
        1
  •  17
  •   Anders    11 年前

    System.Version 是不可序列化的,如果您查看 it's properties on MSDN this approach still works . 那篇文章(虽然很旧,但仍然有效)提供了一个可序列化的版本类,您能切换到它并开始吗?

    通过tomfanning编辑

    using System;
    using System.Globalization;
    namespace CubicOrange.Version
    {
        /// <summary>
        /// Serializable version of the System.Version class.
        /// </summary>
        [Serializable]
        public class ModuleVersion : ICloneable, IComparable
        {
            private int major;
            private int minor;
            private int build;
            private int revision;
            /// <summary>
            /// Gets the major.
            /// </summary>
            /// <value></value>
            public int Major
            {
                get
                {
                    return major;
                }
                set
                {
                    major = value;
                }
            }
            /// <summary>
            /// Gets the minor.
            /// </summary>
            /// <value></value>
            public int Minor
            {
                get
                {
                    return minor;
                }
                set
                {
                    minor = value;
                }
            }
            /// <summary>
            /// Gets the build.
            /// </summary>
            /// <value></value>
            public int Build
            {
                get
                {
                    return build;
                }
                set
                {
                    build = value;
                }
            }
            /// <summary>
            /// Gets the revision.
            /// </summary>
            /// <value></value>
            public int Revision
            {
                get
                {
                    return revision;
                }
                set
                {
                    revision = value;
                }
            }
            /// <summary>
            /// Creates a new <see cref="ModuleVersion"/> instance.
            /// </summary>
            public ModuleVersion()
            {
                this.build = -1;
                this.revision = -1;
                this.major = 0;
                this.minor = 0;
            }
            /// <summary>
            /// Creates a new <see cref="ModuleVersion"/> instance.
            /// </summary>
            /// <param name="version">Version.</param>
            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");
                        }
                    }
                }
            }
            /// <summary>
            /// Creates a new <see cref="ModuleVersion"/> instance.
            /// </summary>
            /// <param name="major">Major.</param>
            /// <param name="minor">Minor.</param>
            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;
            }
            /// <summary>
            /// Creates a new <see cref="ModuleVersion"/> instance.
            /// </summary>
            /// <param name="major">Major.</param>
            /// <param name="minor">Minor.</param>
            /// <param name="build">Build.</param>
            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;
            }
            /// <summary>
            /// Creates a new <see cref="ModuleVersion"/> instance.
            /// </summary>
            /// <param name="major">Major.</param>
            /// <param name="minor">Minor.</param>
            /// <param name="build">Build.</param>
            /// <param name="revision">Revision.</param>
            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
            /// <summary>
            /// Clones this instance.
            /// </summary>
            /// <returns></returns>
            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
            /// <summary>
            /// Compares to.
            /// </summary>
            /// <param name="obj">Obj.</param>
            /// <returns></returns>
            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
            /// <summary>
            /// Equalss the specified obj.
            /// </summary>
            /// <param name="obj">Obj.</param>
            /// <returns></returns>
            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;
            }
            /// <summary>
            /// Gets the hash code.
            /// </summary>
            /// <returns></returns>
            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);
            }
            /// <summary>
            /// Operator ==s the specified v1.
            /// </summary>
            /// <param name="v1">V1.</param>
            /// <param name="v2">V2.</param>
            /// <returns></returns>
            public static bool operator ==(ModuleVersion v1, ModuleVersion v2)
            {
                return v1.Equals(v2);
            }
            /// <summary>
            /// Operator &gt;s the specified v1.
            /// </summary>
            /// <param name="v1">V1.</param>
            /// <param name="v2">V2.</param>
            /// <returns></returns>
            public static bool operator >(ModuleVersion v1, ModuleVersion v2)
            {
                return (v2 < v1);
            }
            /// <summary>
            /// Operator &gt;=s the specified v1.
            /// </summary>
            /// <param name="v1">V1.</param>
            /// <param name="v2">V2.</param>
            /// <returns></returns>
            public static bool operator >=(ModuleVersion v1, ModuleVersion v2)
            {
                return (v2 <= v1);
            }
            /// <summary>
            /// Operator !=s the specified v1.
            /// </summary>
            /// <param name="v1">V1.</param>
            /// <param name="v2">V2.</param>
            /// <returns></returns>
            public static bool operator !=(ModuleVersion v1, ModuleVersion v2)
            {
                return (v1 != v2);
            }
            /// <summary>
            /// Operator &lt;s the specified v1.
            /// </summary>
            /// <param name="v1">V1.</param>
            /// <param name="v2">V2.</param>
            /// <returns></returns>
            public static bool operator <(ModuleVersion v1, ModuleVersion v2)
            {
                if (v1 == null)
                {
                    throw new ArgumentNullException("v1");
                }
                return (v1.CompareTo(v2) < 0);
            }
            /// <summary>
            /// Operator &lt;=s the specified v1.
            /// </summary>
            /// <param name="v1">V1.</param>
            /// <param name="v2">V2.</param>
            /// <returns></returns>
            public static bool operator <=(ModuleVersion v1, ModuleVersion v2)
            {
                if (v1 == null)
                {
                    throw new ArgumentNullException("v1");
                }
                return (v1.CompareTo(v2) <= 0);
            }
            /// <summary>
            /// Toes the string.
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                if (this.build == -1)
                {
                    return this.ToString(2);
                }
                if (this.revision == -1)
                {
                    return this.ToString(3);
                }
                return this.ToString(4);
            }
            /// <summary>
            /// Toes the string.
            /// </summary>
            /// <param name="fieldCount">Field count.</param>
            /// <returns></returns>
            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");
            }
        }
    }
    
        2
  •  14
  •   yclkvnc    11 年前

    我更喜欢使用下面的方法,所以我的类中只有一个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;
        }
    }
    
        3
  •  7
  •   atman    11 年前

    您可以使用字符串代理属性:

    [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);
        } 
    }
    
        4
  •  1
  •   Rubens Farias    15 年前

    您需要定义您的 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
                       }
        );
    

    我得到了这个输出:

    <?xml version="1.0" encoding="ibm850"?>
    <Version xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Build>111</Build>
      <Major>1</Major>
      <MajorRevision>0</MajorRevision>
      <Minor>1</Minor>
      <MinorRevision>10</MinorRevision>
      <Revision>10</Revision>
    </Version>
    
        5
  •  1
  •   nodots    11 年前

    更准确地说,, 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);
    }
    
        6
  •  1
  •   rshea0    9 年前

    我已经清理了Nick Craver的实现,使其更加简洁易读,添加了XML序列化支持(使用属性而不是单独的元素),实现了一个字符串类型转换器,并修复了可能出现NullReferenceException或无限循环(从内部调用重载运算符)的两个比较问题。

    我还使用了一些C#6特性。

    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<VersionCode>, IEquatable<VersionCode>
    {
      [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<string>(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);
      }
    }