Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> перегрузка операторов, generic classes 
:(
    Опции темы
PaZ1T1V
Дата 1.10.2009, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 169
Регистрация: 26.2.2008
Где: Багдад )

Репутация: нет
Всего: нет



Доброго времени суток, уважаемые.
Есть такой вопросец, может кто подскажет, перейдем сразу к нему:
Есть базовый абстрактный generic класс Digit<T>, в нем перегружены операторы сравнения и оператооры арифметических действий, есть три класса  наследника: Fraction, Double, Complex. Классы Fraction и Double рапботают просто замечательно, но класс Complex должен быть параметризованным, то есть его элементами могут быть как и Double, так и Fraction,  итак у нас в итоге есть класс Complex<T1>, если в нем не определить значение типа T1, то он ругается на неопределенные в типе T1 операторы, это и понятно, ему никто не указывал на то, каких классов может быть T1, а если написать Complex<T1> where T1: Digit<Complex<T1>> (ужасная конструкция, но в какой то статье или на форуме я взял такую реализацию и она имеет место быть - работает!!!), то он пишет такую ошибку:
The type 'megaCalculator.ComplexDigit<T1>' cannot be used as type parameter 'T' in the generic type or method 'megaCalculator.Digit<T>'. There is no implicit reference conversion from 'megaCalculator.ComplexDigit<T1>' to 'System.IEquatable<megaCalculator.ComplexDigit<T1>>'.я понимаю что это бред, но как с этим бороться ? может кто подскажет ??? А да, забыл, еще определил интерфейс IDigit<T> на уровне с базовым классом, правда не знаю зачем, но сделал это smile)
Вот коды классов:
а) работают smile)
Код

    
      interface IDigit<T>  
    {       
          T NumberDegree(int degree);
          T Reverse();
          T Copy();   
    }

        abstract public class Digit<T> where T : class, IEquatable<T>
    {
        public static Digit<T> operator +(Digit<T> A, Digit<T> B)
        {
            return (Digit<T>)(A + B);
        }

        public static Digit<T> operator -(Digit<T> A, Digit<T> B)
        {
            return (Digit<T>)(A - B);
        }

        public static Digit<T> operator *(Digit<T> A, Digit<T> B)
        {
            return (Digit<T>)(A * B);
        }

        public static Digit<T> operator /(Digit<T> A, Digit<T> B)
        {
            return (Digit<T>)(A * B);
        }

        public static bool operator >(Digit<T> A, Digit<T> B)
        {
            return false;
        }

        public static bool operator <(Digit<T> A, Digit<T> B)
        {
            return false;
        }

        public static bool operator ==(Digit<T> value1, Digit<T> value2)
        {
            if ((object)value1 == (object)value2)
                return true;
            if ((object)value1 == null)
                return false;
            return value1.Equals(value2);
        }
        public static bool operator !=(Digit<T> value1, Digit<T> value2)
        {
            if ((object)value1 == (object)value2)
                return false;
            if ((object)value1 == null)
                return true;
            return !value1.Equals(value2);
        }
        public override bool Equals(object obj)
        {
            T key = obj as T;
            // Эта проверка оставлена только для читабельности. Рельно она не нужна.
            if ((object)key == null)
                return false;
            return ((IEquatable<T>)this).Equals(key);
        }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        protected int _hashCode;
        public override int GetHashCode()
        {
            System.Diagnostics.Debug.Assert(_hashCode != 0);
            return _hashCode;
        }         
    }

     public class SimpleFraction : Digit<SimpleFraction>, IEquatable<SimpleFraction>, IDigit<SimpleFraction>, IDisposable 
    {
        private int Numerator;
        private int Denomerator;

        public SimpleFraction()
        {
            this.Numerator = 0;
            this.Denomerator = 1;
        }
         //...... не важно что там дальше он большой и работает :)
     }

      class Double : Digit<Double>, IDigit<Double>, IEquatable<Double>, IDisposable 
    {
        double value;

        public Double()
        {
            this.value = 0;
        }

         //тоже работает :))
     }



б) ошибки :((
Код


// если вот так определить 

public class ComplexDigit<T1> : IDigit<ComplexDigit<T1>>, IEquatable<ComplexDigit<T1>>, IDisposable
    {
        T1 IMpart;
        T1 REpart;
// то ошибки в местах  где есть операторы +, -, *, /, к примеру:


        public static ComplexDigit<T1> operator -(ComplexDigit<T1> A, ComplexDigit<T1> B)
        {
            return new ComplexDigit<T1>((T1)(A.REpart - B.REpart), (T1)(A.IMpart - B.IMpart)); //ошибка : тип T1 не знает что такое оператор вычитания
        }
}

//а если вот так определить 
Код

 public class ComplexDigit<T1> where T1 : Digit<ComplexDigit<T1>>, IDigit<ComplexDigit<T1>>, IEquatable<ComplexDigit<T1>>, IDisposable //ошибка
    {

}

то ссылается на интерфейс 
Inconsistent accessibility: constraint type 'megaCalculator.IDigit<megaCalculator.ComplexDigit<T1>>' is less accessible than 'megaCalculator.ComplexDigit<T1>'    

убираем интерфейс  из списка родителей и снова ошибка 

The type 'megaCalculator.ComplexDigit<T1>' cannot be used as type parameter 'T' in the generic type or method 'megaCalculator.Digit<T>'. There is no implicit reference conversion from 'megaCalculator.ComplexDigit<T1>' to 'System.IEquatable<megaCalculator.ComplexDigit<T1>>'.
 smile  smile  smile  smile  smile  smile  smile 

--------------------
[size=8]Atention please!!![/size]
[size=6]Кривые руки[/size]
PM MAIL WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
mr.DUDA
Дата 1.10.2009, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



generic'и с операторами в шарпе не дружат, где-то читал статью на эту тему, что-то говорилось про вывод типов который в C# недоделанный )


--------------------
user posted image
PM MAIL WWW   Вверх
PaZ1T1V
Дата 1.10.2009, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 169
Регистрация: 26.2.2008
Где: Багдад )

Репутация: нет
Всего: нет



generic'и с операторами в шарпе не дружат, где-то читал статью на эту тему, что-то говорилось про вывод типов который в C# недоделанный ) 

Cпасибо за ответ mr.Duda, но, что они не доделанные я не знал.... как то странно все, а как мне быть? МОЖЕТ подскажешь что??? еще раз напомню задачу.... лучше так
                         Digit<T>
                              |
               ------------------------
               |              |             |
             Fraction Double  Complex<T1>
где Т и Т1 - это по сути одно и тоже - это число, только Т = {Fraction, Double, Complex<>}, а Т1 = {Fraction, Double}

Как реализовать  ???? может можно обойтись как нибудь без параметризации Comlex'a ???? только мне что-то в голову не приходит ничего.... Interface'ами можно конечно, типа 
                     Idigit
                        |
                 ------------
                 |             |
            Ifraction     Idouble
только мне кажется это гемор еще тот, куча повторяющегося кода будет или я не прав? если нет, то можно ли мне объяснить почему и как это сделать??? а можно ли не перегружать операторы, а воспользоваться какими то системными методами типа Add, Sub and etc... ?????
smile устал уже smile  

--------------------
[size=8]Atention please!!![/size]
[size=6]Кривые руки[/size]
PM MAIL WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
mr.DUDA
Дата 2.10.2009, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



PaZ1T1V, компилятор не проглотит арифметические и прочие операторы над типами, которые не указаны явно (а параметризуются в generic-е). Можно извратиться и сделать интерфейсы а-ля INumber с методами Add, Sub и т.п., реализовать враппер над интом и т.п., но это как ты сам понимаешь гемор ещё тот. 

В С++ такого ограничения нет.


--------------------
user posted image
PM MAIL WWW   Вверх
PaZ1T1V
Дата 2.10.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 169
Регистрация: 26.2.2008
Где: Багдад )

Репутация: нет
Всего: нет



Цитата(mr.DUDA @ 2.10.2009,  16:29)
PaZ1T1V, компилятор не проглотит арифметические и прочие операторы над типами, которые не указаны явно (а параметризуются в generic-е). Можно извратиться и сделать интерфейсы а-ля INumber с методами Add, Sub и т.п., реализовать враппер над интом и т.п., но это как ты сам понимаешь гемор ещё тот. 

В С++ такого ограничения нет.

ага, понимаю.... гемор это еще тот, а в ++ такого ограничения нету, это я знаю, там с этим делом легче, да, ничего не остается как делать интерфейсы и делать в них методы Addition и еже с ними., такая мысль возникла у меня когда я столкнулся с невозможностью перегрузить операторы для неявных типов, спасиб за ответ, просто я думал есть вариант без "мистер знает толк в извращениях-с"  
--------------------
[size=8]Atention please!!![/size]
[size=6]Кривые руки[/size]
PM MAIL WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0446 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.