Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/35: Рейтинг темы: голосов - 35, средняя оценка - 4.69
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
1

Перегрузить оператор ==, но не потерять возможности сравнения с null

11.07.2012, 16:13. Показов 7342. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Как перегрузить оператор == для класса, но так чтобы проверка на null осталась работоспособной.
Потому как если я перегружаю оператор == в классе
C#
1
2
3
4
        public static bool operator == (Person one, Person two)
        {
            return one.age == two.age;
        }
А потом пытаюсь сделать это

C#
1
2
3
Person oldest = null;
...
if (oldest == null) //вылет. Оно логично, ведь я пытаюсь обратиться к полю age у null"
Перегрузка оператора == в виде
C#
1
2
3
4
5
6
7
        public static bool operator == (Person one, Person two)
        {
            if (one == null || two == null)//проверить на null
                return false;
 
            return one.age == two.age;
        }
Ничего не даёт, теперь получается что я в оператор == вызываю оператор == что тоже плохо, так как же проверить адрес, а не сам объект?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.07.2012, 16:13
Ответы с готовыми решениями:

Не получается перегрузить оператор сравнения
class vremya { private: int h,m,s; public: void operator ++(int) { ...

Для шаблонного класса перегрузить оператор присваивания, copy-конструктор, объекты cin и cout, оператор *
Помогите в следующем: Для класса шаблона следует перегрузить оператор присваивания, конструктор...

Перегрузить операторы сравнения и отсортировать
Добрый день. Требуется отсортировать данные из файла формата "тип1 тип2 тип3 тип4" только по "тип1"...

Как перегрузить оператор<< и оператор>> ?
Доброго времени суток. Застрял на двух вопросах и не как не могу найти инфу которвя мне помогла бы...

17
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.07.2012, 16:18 2
Gepar,
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    internal class Program
    {
        public class Person
        {
            public int age { get; set; }
            public static bool operator ==(Person one, Person two)
            {
                if ((Object)one == null || (Object)two == null)//проверить на null
                    return false;
 
                return one.age == two.age;
            }
            public static bool operator !=(Person one, Person two)
            {
                if ((Object)one == null || (Object)two == null)//проверить на null
                    return true;
 
                return one.age != two.age;
            }
            public Person()
            {
                this.age = 10;
            }
        }       
 
        private static void Main(string[] args)
        {
            Person p1 = new Person();
            Person p2 = new Person();
            Console.WriteLine(p1==p2); // Output: True
            Console.ReadKey();
        }
    }
2
543 / 544 / 181
Регистрация: 16.03.2012
Сообщений: 1,160
Записей в блоге: 2
11.07.2012, 16:20 3
C#
1
2
3
4
5
6
public static bool operator == (Person one, Person two)
{
 if (one == null || two == null)
    return false;
return true;
}
0
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
11.07.2012, 16:55 4
Один из вариантов - приведение к object для сравнения, как предложил Psilon.
Еще возможно использование ReferenceEquals:
C#
1
2
3
4
5
6
7
8
public static bool operator ==(Person a, Person b)
        {
            if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
                //return false;
                //При сравнении null vs null лучше возвращать true.
                return ReferenceEquals(a, b);
            return a.age == b.age;
        }
2
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
11.07.2012, 17:08  [ТС] 5
buntar, и что же ты изменил? Проверку то оставил ту же самую.
Psilon, твой вариант тоже не работает, по прежнему будет ошибка получаться. Приведу ка я весь код наверное. Код весьма прост, хоть и не очень короткий, это учебный пример так что допустимость значений проверяется только там где это важно для работоспособности кода, а не корректности результатов. Проблема возникает лишь с оператором == и последующим его (случайным) использованием при сравнении с null.

1) Вариант который собирается (оператор == и != закомментирован потому и собирается !)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace People
{
    public class Person
    {
        private string name;
        private int age;
 
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
 
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
            }
        }
 
        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
 
        public override string ToString()
        {
            return name + ", " + age;
        }
 
 
        public static bool operator >(Person one, Person two)
        {
            return one.Age > two.Age;
        }
 
        public static bool operator <(Person one, Person two)
        {
            return !(one > two);
        }
 
        /*
        public static bool operator == (Person one, Person two)
        {
            if (one == null || two == null)
                return false;
 
            return one.age == two.age;
        }
       
 
        
        public static bool operator != (Person one, Person two)
        {
            return ! (one == two);
        }
        
        */
 
        public static bool operator >= (Person one, Person two)
        {
            return (one>two || one.age == two.age);
        }
 
        public static bool operator <=(Person one, Person two)
        {
            return (one < two || one.age == two.age);
        }
    }
 
 
 
    //хранит объекты Person, как ключ будет служить имя персоны
    public class People : DictionaryBase, ICloneable
    {
        public void Add(Person toAdd)
        {
            Dictionary.Add(toAdd.Name, toAdd);
        }
 
        public void Remove(Person toRemove)
        {
            Dictionary.Remove(toRemove.Name);
        }
 
        
        public Person this[string key]
        {
            get
            {
                return (Person)Dictionary[key];
            }
        }
 
 
        //для for each
        public new IEnumerator GetEnumerator()
        {
            foreach (object person in Dictionary.Values)
                yield return (Person)person;
        }
 
 
        //возвращает массив самых старших персон (количество элементов зависит от того
        //у скольки персон наибольший возраст совпадёт)
        public Person[] GetOldest()
        {
            int count = 0;
            Person oldest = null;
 
            foreach (object value in Dictionary.Values)
                //если oldest ещё ничего не назначалось то можно считать
                //что любая персона по сравнению с null объектом старше
                if (oldest == null) //ВЫВАЛИТСЯ ЕСЛИ ПЕРЕГРУЗКА ОПЕРАТОРА == БУДЕТ ДОСТУПНА
                    oldest = value as Person;
                //иначе сохраняем указатель только если текущая персона старше
                else if (value as Person > oldest)
                    oldest = value as Person;
 
            if (oldest != null)
            {
                foreach (object value in Dictionary.Values)
                    if ((value as Person).Age == oldest.Age)
                        count++;
 
                Person[] result = new Person[count];
                foreach (object value in Dictionary.Values)
                    if ((value as Person).Age == oldest.Age)
                        result[--count] = value as Person;
                return result;
            }
 
            return null;
        }
 
        public object Clone()
        {
            People newPeople = new People();
            foreach (Person pers in Dictionary.Values)
                newPeople.Dictionary.Add(pers.Name, pers);
 
            return newPeople;
        }
    }
 
 
 
    class Program
    {
        static void Main(string[] args)
        {
            People pp = new People();
            pp.Add(new Person("Adam", 22));
            pp.Add(new Person("Eva", 18));
            pp.Add(new Person("Andy", 22));
            pp.Add(new Person("Hero", 22));
 
            Person[] res = pp.GetOldest();
 
            if(res != null)
            foreach (Person pers in res)
                Console.WriteLine(pers);
        }
    }
}
Вариант 2:тоже самое но оператор == , != расскомментированы. Ошибка происходит когда идёт проверка на null в функции GetOldest класса People.

Добавлено через 4 минуты
С ReferenceEquals сработало. Перегрузка приняла вид
C#
1
2
3
4
5
6
7
8
9
10
        
        public static bool operator == (Person one, Person two)
        {
            if (ReferenceEquals(one, null) && ReferenceEquals(two, null))
                return true;
            else if (ReferenceEquals(one, null) || ReferenceEquals(two, null))
                return false;
 
            return one.age == two.age;
        }
и теперь учитываются оба варианта (когда идёт сравнение с null и когда оба объекта null).

Добавлено через 2 минуты
Хотя с приведениями к Object тоже сработало, нужно только обе проверки было сделать чтобы было так:
C++
1
2
3
4
5
6
7
8
9
        public static bool operator == (Person one, Person two)
        {
            if ((Object)one == null && (Object)two==null)
                return true;
            else if ((Object)one == null || (Object)two == null)
                return false;
 
            return one.age == two.age;
        }
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.07.2012, 17:08 6
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace People
{
    public class Person
    {
        private string name;
        private int age;
 
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
 
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
            }
        }
 
        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
 
        public override string ToString()
        {
            return name + ", " + age;
        }
 
 
        public static bool operator >(Person one, Person two)
        {
            if ((object)one == null || (object)two == null)
                return false;
            return one.Age > two.Age;
        }
 
        public static bool operator <(Person one, Person two)
        {
            return !(one > two);
        }
 
        
        public static bool operator == (Person one, Person two)
        {
            if ((object)one == null || (object)two == null)
                return false;
 
            return one.age == two.age;
        }
       
 
        
        public static bool operator != (Person one, Person two)
        {
            if ((object)one == null || (object)two == null)
                return false;
            return one.age != two.age;
        }
        
 
        public static bool operator >=(Person one, Person two)
        {
            return (one > two || one.age == two.age);
        }
 
        public static bool operator <=(Person one, Person two)
        {
            return (one < two || one.age == two.age);
        }
    }
 
 
 
    //хранит объекты Person, как ключ будет служить имя персоны
    public class People : DictionaryBase, ICloneable
    {
        public void Add(Person toAdd)
        {
            Dictionary.Add(toAdd.Name, toAdd);
        }
 
        public void Remove(Person toRemove)
        {
            Dictionary.Remove(toRemove.Name);
        }
 
 
        public Person this[string key]
        {
            get
            {
                return (Person)Dictionary[key];
            }
        }
 
 
        //для for each
        public new IEnumerator GetEnumerator()
        {
            foreach (object person in Dictionary.Values)
                yield return (Person)person;
        }
 
 
        //возвращает массив самых старших персон (количество элементов зависит от того
        //у скольки персон наибольший возраст совпадёт)
        public Person[] GetOldest()
        {
            int count = 0;
            Person oldest = null;
 
            foreach (object value in Dictionary.Values)
                //если oldest ещё ничего не назначалось то можно считать
                //что любая персона по сравнению с null объектом старше
                if (oldest == null) //ВЫВАЛИТСЯ ЕСЛИ ПЕРЕГРУЗКА ОПЕРАТОРА == БУДЕТ ДОСТУПНА
                    oldest = value as Person;
                //иначе сохраняем указатель только если текущая персона старше
                else if (value as Person > oldest)
                    oldest = value as Person;
 
            if (oldest != null)
            {
                foreach (object value in Dictionary.Values)
                    if ((value as Person).Age == oldest.Age)
                        count++;
 
                Person[] result = new Person[count];
                foreach (object value in Dictionary.Values)
                    if ((value as Person).Age == oldest.Age)
                        result[--count] = value as Person;
                return result;
            }
 
            return null;
        }
 
        public object Clone()
        {
            People newPeople = new People();
            foreach (Person pers in Dictionary.Values)
                newPeople.Dictionary.Add(pers.Name, pers);
 
            return newPeople;
        }
    }
 
 
 
    class Program
    {
        static void Main(string[] args)
        {
            People pp = new People();
            pp.Add(new Person("Adam", 22));
            pp.Add(new Person("Eva", 18));
            pp.Add(new Person("Andy", 22));
            pp.Add(new Person("Hero", 22));
 
            Person[] res = pp.GetOldest();
 
            if (res != null)
                foreach (Person pers in res)
                    Console.WriteLine(pers);
        }
    }
}
0
Gepar
11.07.2012, 17:08  [ТС]
  #7

Не по теме:

deleted

0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.07.2012, 17:11 8
Gepar, да, как раз хотел уточнить, что при такой организации null не участвует в упорядочивании. Сами догадались
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
11.07.2012, 17:13 9
Не забудьте также переопределить метод Equals и GetHashCode, чтобы не было неоднозначности в сравнении двух экземпляров.
0
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
11.07.2012, 17:19 10
Цитата Сообщение от Gepar Посмотреть сообщение
С ReferenceEquals сработало. Перегрузка приняла вид
C#
1
2
3
4
5
6
7
8
9
10
        
        public static bool operator == (Person one, Person two)
        {
            if (ReferenceEquals(one, null) && ReferenceEquals(two, null))
                return true;
            else if (ReferenceEquals(one, null) || ReferenceEquals(two, null))
                return false;
 
            return one.age == two.age;
        }
и теперь учитываются оба варианта (когда идёт сравнение с null и когда оба объекта null).
Зачем столько if - ов и else -ов. Мой код уже проверял все возможности:
C#
1
2
3
4
5
6
public static bool operator ==(Person a, Person b)
        {
            if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
                return ReferenceEquals(a, b);
            return a.age == b.age;
        }
Добавлено через 4 минуты
Цитата Сообщение от kolorotur Посмотреть сообщение
Не забудьте также переопределить метод Equals и GetHashCode, чтобы не было неоднозначности в сравнении двух экземпляров.
Если уж переопределять Object.Equals, то правильнее будет писать и Equals интерфейса IEquatable<Person>. А в этом случае, оператор сравнения, лучше уже переписывать на его основе...
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
11.07.2012, 17:23 11
Цитата Сообщение от Lasur Посмотреть сообщение
Если уж переопределять Equals, то правильнее будет писать и Equals интерфейса IEquatable
Не правильнее.
IEquatable и метод Equals класса object - это разные вещи.
По гайдлайнам при перегрузке оператора == и !=, также нужно переопределять метод Equals и GetHashCode - именно для постоянства реализации.
Если же хочется внести дополнительное понятие "равенства" или "эквивалентности" объектов, тогда уже можно реализовать IEquatable.
0
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
11.07.2012, 17:33  [ТС] 12
Класс не претендует на "доделанный, протестированный и быстро работающий", как видите там и ToString() не перегружено даже для вывода объектов класса, я перфекционизмом не страдаю

Цитата Сообщение от kolorotur Посмотреть сообщение
По гайдлайнам при перегрузке оператора == и !=, также нужно переопределять метод Equals и GetHashCode
Вот тут кстати интересная вещь: код собирался и не жаловался ни на что, но стоило мне попытаться добавить ещё итерацию по Возрастам (Ages), те просто левую функцию возвращающую IEnumerator (то что добавил кстати не хочет вызываться ещё как планировал, но не суть), как VS внезапно вспомнила что я оператор == и != перегрузил, а вот Equals и GetHaskCode - нет. А ведь до этого молчала же.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
11.07.2012, 17:36 13
Цитата Сообщение от Gepar Посмотреть сообщение
Класс не претендует на "доделанный, протестированный и быстро работающий"
А класс и не должен на это претендовать.
На то, чтобы класс таковым являлся, должны претендовать вы, как разработчик этого класса.
В противном случае - вон из профессии

Цитата Сообщение от Gepar Посмотреть сообщение
код собирался и не жаловался ни на что, но стоило мне попытаться добавить ещё итерацию по Возрастам (Ages), те просто левую функцию возвращающую IEnumerator (то что добавил кстати не хочет вызываться ещё как планировал, но не суть), как VS внезапно вспомнила что я оператор == и != перегрузил, а вот Equals и GetHaskCode - нет. А ведь до этого молчала же.
Студия этим грешит время от времени.
Я пока точно не понял: что-то в коде не так или студийный парсер глючит, но тоже не раз замечал, что некоторые ворнинги генерируются при одном билде и пропадают на другом (без изменения кода).
1
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
11.07.2012, 17:49  [ТС] 14
Цитата Сообщение от kolorotur Посмотреть сообщение
А класс и не должен на это претендовать.
На то, чтобы класс таковым являлся, должны претендовать вы, как разработчик этого класса.
В противном случае - вон из профессии
Я ленивый, попробовал пару раз перегрузить ToString() - получилось нормально вот и перестал перегружать во всех остальных классах заостряя внимание на ту тему которая описывается в текущей главе книги, в данном случае перегрузка операторов и итераторы. С остальным тоже самое, лень реализовывать по 100 раз тоже самое если это всего лишь учебный пример и он никому после его написания не понадобится.

Цитата Сообщение от kolorotur Посмотреть сообщение
Студия этим грешит время от времени.
А, ну тогда всё в порядке, ато я уже подумал было что в с# есть какой-то хитрый таракан в стиле "если у вас процессор Intel, а количество функций в классе больше 5 и вы перегрузили оператор == то вы обязаны перегрузить ещё и ...". Мало ли
0
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
11.07.2012, 17:49 15
Цитата Сообщение от kolorotur Посмотреть сообщение
IEquatable и метод Equals класса object - это разные вещи.
По гайдлайнам при перегрузке оператора == и !=, также нужно переопределять метод Equals и GetHashCode - именно для постоянства реализации.
Если уж говорить о гайдлайнах - не так давно интересовался как нужно правильно использовать все возможные методы сравнения (static object.Equals, instance object.Equals, ReferenceEquals, Equals<T>, ==, !=). В итоге, побродив по просторам интернета, в частности по StackOverflow, наткнулся на книгу Effective C# в которой в деталях расписывался, в том числе, этот момент. Так вот, ее автор прямо настаивает на использовании обобщенного Equals в случае переопределения обычного.
В частности, он приводит следующую реализацию object.Equals:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Foo : IEquatable<Foo>
{
    public override bool Equals(object right)
    {
        if (object.ReferenceEquals(right, null))
            return false;
        if (object.ReferenceEquals(this, right))
            return true;
        if (this.GetType() != right.GetType())
            return false;
        return this.Equals(right as Foo);
    }
    public bool Equals(Foo other)
    {
        // ...
    }
}
Объекты разного типа редко считаются одинаковыми, посему обычному Equals удобнее вызывать Equals обобщенный после проверки на соответствие типов.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
11.07.2012, 18:03 16
Цитата Сообщение от Gepar Посмотреть сообщение
я уже подумал было что в с# есть какой-то хитрый таракан
Вполне может быть, что он действительно есть.
Но что студия время от времени, казалось бы, без причины то выдает, то не выдает ворнинги - случается.

Цитата Сообщение от Lasur Посмотреть сообщение
ее автор прямо настаивает на использовании обобщенного Equals в случае переопределения обычного.
Ну это примерно то же самое, что рекомендации вместе с интерфейсом IEnumerable<T> реализовывать так же IEnumerable.
Они отнюдь не лишены смысла, но студия ругаться не будет, если их оба не реализовывать.

Цитата Сообщение от Lasur Посмотреть сообщение
Объекты разного типа редко считаются одинаковыми
Я один и тот же тип имел в виду.
Конечно, если при разных обстоятельствах условия эквивалентности меняются, то тут лучше писать отдельный класс, реализующий IEqualityComparer для каждого условия.
0
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
11.07.2012, 18:27 17
Цитата Сообщение от kolorotur Посмотреть сообщение
Я один и тот же тип имел в виду.
Конечно, если при разных обстоятельствах условия эквивалентности меняются, то тут лучше писать отдельный класс, реализующий IEqualityComparer для каждого условия.
Или я вас не понял, или вы меня... Под словами
Цитата Сообщение от Lasur Посмотреть сообщение
Объекты разного типа редко считаются одинаковыми, посему обычному Equals удобнее вызывать Equals обобщенный после проверки на соответствие типов.
я имел в виду следующее:
если мы перегружаем object.Equals(object obj), то ,чаще всего, попросту осуществляется попытка свести obj к типу нашего класса MyClass и потом производить нужные сравнения. Так вот логичнее всего вынести эти сравнения в Equals(MyClass obj).

Цитата Сообщение от kolorotur Посмотреть сообщение
Ну это примерно то же самое, что рекомендации вместе с интерфейсом IEnumerable<T> реализовывать так же IEnumerable.
Они отнюдь не лишены смысла, но студия ругаться не будет, если их оба не реализовывать.
Разве IEnumerable<T> не наследует IEnumerable? Кроме того, ругань студии охватывает довольно мало ситуаций... Например, у мелкомягких есть рекомендации по добавлению дополнительного статического метода для любого перегруженного оператора, но студия даже не заикается об этом...
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
11.07.2012, 19:08 18
Цитата Сообщение от Lasur Посмотреть сообщение
если мы перегружаем object.Equals(object obj), то ,чаще всего, попросту осуществляется попытка свести obj к типу нашего класса MyClass и потом производить нужные сравнения.
Так точно. Для этого дела даже паттерн есть.

Цитата Сообщение от Lasur Посмотреть сообщение
Так вот логичнее всего вынести эти сравнения в Equals(MyClass obj).
Полностью с вами согласен.
Но проблема возникает тогда, когда мы пытаемся наш сферический класс в вакууме, реализовавший IEquatable<MyClass>, передать ссылочкой в какой-нибудь метод, написанный до появления генериков (которых во фреймворке - пруд пруди).
Этот метод будет использовать Equals, определенный у object, а мы будем наблюдать странную работу приложения и чесать репу, размышляя, что за фигня тут творится

Цитата Сообщение от Lasur Посмотреть сообщение
Разве IEnumerable<T> не наследует IEnumerable?
Наследует. Я, честно сказать, тоже не вижу причину в такой рекомендации. Возможно, возникают какие-то сложности или непонятки в случае наследования и перереализации наследником этого интерфейса - вот и сделали из частного случая общую рекомендацию.
Но это так - мои домыслы о действительных причинах.

Цитата Сообщение от Lasur Посмотреть сообщение
у мелкомягких есть рекомендации по добавлению дополнительного статического метода для любого перегруженного оператора, но студия даже не заикается об этом...
Полезные рекомендации, кстати.
Но, говоря конкретно о ругани, - это рекомендации для написания CLS-compliant кода. Если вы пометите класс, перегружающий операторы, как CLS-compliant, то, я думаю, студия будет ругаться.
1
11.07.2012, 19:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.07.2012, 19:08
Помогаю со студенческими работами здесь

Проиллюстрировать возможности операций отношения (сравнения)
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int main() { int...

Для класса Vector перегрузить операторы присваивания, сравнения, ввода и вывода
срочно помогите написать программу, желательно с комментариями если можно)) Для класса Vector...

Как перегрузить методы Equals() и GetHashCode(), для сравнения свойств объектов?
Есть два объекта класса Квадрат.Необходимо сравнить их по площади заданной свойством. Для этого...

Как перегрузить операции отношения для реализации значимой семантики сравнения объектов
Добрый вечер, уважаемые участники форума. Есть поставленная задача с наследованием: Она в...

Перегрузить оператор -
Есть 2 масива если в них есть 2 одинаковых числа то з первого масива что бы изменялось на ноль...

Перегрузить оператор
Хай class Stalk { int length; public: Stalk() { //cout &lt;&lt; &quot;Constructor Stack&quot; &lt;&lt; endl;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru