Язык программирования C#9 и платформа .NET5
// Предположим, что имеется свойство SSN.class Person{public string SSN {get; } = "";public Person(string fName, string lName, int personAge,string ssn){FirstName = fName;LastName = lName;Age = personAge;SSN = ssn;}// Возвратить хеш-код на основе уникальных строковых данных.public override int GetHashCode() => SSN.GetHashCode();}В случае использования в качестве основы хеш-кода свойства, допускающего чтение и запись, вы получите предупреждение. После того, как объект создан, хеш-код должен быть неизменяемым. В предыдущем примере свойство
имеет только методSSN, что делает его допускающим только чтение, и устанавливать его можно только в конструкторе.getЕсли вы не можете отыскать единый фрагмент уникальных строковых данных, но есть переопределенный метод
, который удовлетворяет соглашению о доступе только по чтению, тогда вызывайтеToString()на собственном строковом представлении:GetHashCode()// Возвратить хеш-код на основе значения, возвращаемого// методом ToString() для объекта Person.public override int GetHashCode() => ToString().GetHashCode();Тестирование модифицированного класса Person
Теперь, когда виртуальные члены класса
переопределены, обновите операторы верхнего уровня, чтобы протестировать внесенные изменения:ObjectConsole.WriteLine("***** Fun with System.Object *****\n");// ПРИМЕЧАНИЕ: мы хотим, чтобы эти объекты были идентичными// в целях тестирования методов Equals() и GetHashCode().Person p1 = new Person("Homer", "Simpson", 50, "111-11-1111");Person p2 = new Person("Homer", "Simpson", 50, "111-11-1111");// Получить строковые версии объектов.Console.WriteLine("p1.ToString() = {0}", p1.ToString());Console.WriteLine("p2.ToString() = {0}", p2.ToString());// Протестировать переопределенный метод Equals().Console.WriteLine("p1 = p2?: {0}", p1.Equals(p2));// Протестировать хеш-коды.// По-прежнему используется хеш-значение SSNConsole.WriteLine("Same hash codes?: {0}", p1.GetHashCode() == p2.GetHashCode());Console.WriteLine();// Изменить значение Age объекта p2 и протестировать снова.p2.Age = 45;Console.WriteLine("p1.ToString() = {0}", p1.ToString());Console.WriteLine("p2.ToString() = {0}", p2.ToString());Console.WriteLine("p1 = p2?: {0}", p1.Equals(p2));// По-прежнему используется хеш-значение SSNConsole.WriteLine("Same hash codes?: {0}", p1.GetHashCode() == p2.GetHashCode());Console.ReadLine();Ниже показан вывод:
***** Fun with System.Object *****p1.ToString() = [First Name: Homer; Last Name: Simpson; Age: 50]p2.ToString() = [First Name: Homer; Last Name: Simpson; Age: 50]p1 = p2?: TrueSame hash codes?: Truep1.ToString() = [First Name: Homer; Last Name: Simpson; Age: 50]p2.ToString() = [First Name: Homer; Last Name: Simpson; Age: 45]p1 = p2?: FalseSame hash codes?: TrueИспользование статических членов класса System.Object
В дополнение к только что рассмотренным членам уровня экземпляра класс
определяет два статических члена, которые также проверяют эквивалентность на основе значений или на основе ссылок. Взгляните на следующий код:System.Objectstatic void StaticMembersOfObject(){// Статические члены System.Object.Person p3 = new Person("Sally", "Jones", 4);Person p4 = new Person("Sally", "Jones", 4);Console.WriteLine("P3 and P4 have same state: {0}",object.Equals(p3, p4));// Р3 и P4 имеют то же самое состояниеConsole.WriteLine("P3 and P4 are pointing to same object: {0}",object.ReferenceEquals(p3, p4));// Р3 и P4 указывают на тот же самый объект}Здесь вы имеете возможность просто отправить два объекта (любого типа) и позволить классу
выяснить детали автоматически. Ниже показан вывод, полученный в результате вызова методаSystem.Objectв операторах верхнего уровня:StaticMembersOfObject()***** Fun with System.Object *****P3 and P4 have the same state: True