可以在类中使用GUID私有属性,以便在GetHashCode覆盖中使用它吗?

sha*_*dow 5 .net c# guid gethashcode

可以在类中使用GUID私有属性,以便在GetHashCode覆盖中使用它吗?

就像是:

public class Voucher : IComparable<Voucher>, IComparable, IEquatable<Voucher>
{
    private Guid? _guid;


    private Guid Guid
    {
        get
        {
            return _guid ?? (_guid = Guid.NewGuid()).GetValueOrDefault();
        }
    }
    public int Id { get; private set; }
    public string Number { get; private set; }
    public DateTime Date { get; private set; }



    public Voucher(string number, DateTime date)
    {
        Number = number;
        Date = date;
    }

    public Voucher(int id, string number, DateTime date)
        : this(number, date)
    {
        Id = id;
    }



    public override bool Equals(object obj)
    {
        return Equals(obj as Voucher);
    }

    public override int GetHashCode()
    {
        return Guid.GetHashCode();
    }

    public override string ToString()
    {
        return String.Format("[{0}] - [{1:dd/MM/yyyy}]", Number, Date);
    }



    #region IComparable<Voucher> Members

    public int CompareTo(Voucher other)
    {
        if (other == null)
            return -1;

        if (Date != other.Date)
            return Date.CompareTo(other.Date);
        else
            return Number.CompareTo(other.Number);
    }

    #endregion

    #region IComparable Members

    public int CompareTo(object obj)
    {
        return CompareTo(obj as Voucher);
    }

    #endregion

    #region IEquatable<Voucher> Members

    public bool Equals(Voucher other)
    {
        if (other != null)
            return (Number == other.Number) && (Date == other.Date);

        return false;
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

昨天我发现为了覆盖GetHashCode,我们只能使用该类的不可变成员/字段.

对于我的许多情况,只有通过Sql Server的标识生成的Id和0的新实例.

因此对于许多新对象(不持久化到数据库,因此Id为0),对象哈希码是相同的.正确?

它会像上面的例子一样使用GUID吗?谢谢.

评论后编辑课程

所以在您发表评论后我将其更改为:

public class Voucher : IComparable<Voucher>, IComparable, IEquatable<Voucher>
    {
        public int Id { get; private set; }
        public string Number { get; private set; }
        public DateTime Date { get; private set; }



        public Voucher(string number, DateTime date)
        {
            Number = number;
            Date = date;
        }

        public Voucher(int id, string number, DateTime date)
            : this(number, date)
        {
            Id = id;
        }



        public override bool Equals(object obj)
        {
            return Equals(obj as Voucher);
        }

        public override int GetHashCode()
        {
            return Number.GetHashCode() ^ Date.GetHashCode();
        }

        public override string ToString()
        {
            return String.Format("[{0}] - [{1:dd/MM/yyyy}]", Number, Date);
        }



        #region IComparable<Voucher> Members

        public int CompareTo(Voucher other)
        {
            if (other == null)
                return -1;

            if (Date != other.Date)
                return Date.CompareTo(other.Date);
            else
                return Number.CompareTo(other.Number);
        }

        #endregion

        #region IComparable Members

        public int CompareTo(object obj)
        {
            return CompareTo(obj as Voucher);
        }

        #endregion

        #region IEquatable<Voucher> Members

        public bool Equals(Voucher other)
        {
            if (other != null)
                return (Number == other.Number) && (Date == other.Date);

            return false;
        }

        #endregion
    }
Run Code Online (Sandbox Code Playgroud)

我想这是可以的,因为凭证是不可改变的.

但是,如果成员编号和日期不是一成不变的,可以访问 - 在课堂外改变?那么解决方案是什么?仅仅记录类"不能在HashCode依赖列表中使用"这样的内容是否足够?

mst*_*sen 0

不。

合约规定两个相等的对象应该有相同的 hashCode。

在您的情况下,如果您创建两个具有相同内容的对象,则两个实例的哈希码将不同。这会破坏契约,并可能破坏依赖 hashCode 的组件的行为。

另外,当您覆盖 时GetHashCode(),您也必须覆盖Equals(object)