none
Создание собственных шаблонов в C# RRS feed

  • Вопрос

  • Необходимо организовать шаблон, представляющий комплексные числа в C#. Описание этого шаблона(основу) написать легко, а вот с перегрузкой операторов("+", "-", "*", "/") для шаблона ничего понять не могу! Вроди бы пишу код по всем правилам, но к примеру при перегрузке оператора "+"(public static MyClass operator+(MyClass a, MyClass b) ) вылазит, по-моему, крайне странное сообщение компилятора об ошибке:"Оператор + не может применяться к операндам Current_Type". Подскажите пожалуйста, как организовать перегрузку операторов для шаблона(желательно, с вразумительными примерами).
    • Перемещено Tagore Bandlamudi 1 октября 2010 г. 21:03 MSDN Forums consolidation (От:Visual C#)
    28 сентября 2010 г. 10:53

Ответы

  • Если коротко - то ошибка вылазит из-за вызова операторов +/ у типа-параметра шаблона. Тип параметра заранее не известен. Гарантировать, что оператор + для него будет определен - нельзя. Хуже того, нельзя даже поставить ограничение на наличее оператора + у типа Current_type.

    Есть варианты со всякой кодогенерацией. Гугл подсказывает Generic Operators и построенный на них Generic Complex Type

    • Предложено в качестве ответа PashaPash 28 сентября 2010 г. 19:23
    • Помечено в качестве ответа I.Vorontsov 30 сентября 2010 г. 12:49
    28 сентября 2010 г. 19:23

Все ответы

  • вот писал когда то:

    using System;
    class Complex
    {
     public int a;
     public int b;
     
     public Complex()
     {
     a = 1;
     b = 1;
     }
     
     public Complex(int a,int b)
     {
      this.a = a;
      this.b = b;
     }
     
     public void Print()
     {
      if(b>=0)
      Console.WriteLine("{0} + {1}i",a,b);
      else
      Console.WriteLine("{0} - {1}i",a,-b);  
     }
     
     public static Complex operator+(Complex op1,Complex op2)
     {
      Complex res = new Complex();
      res.a = op1.a+op2.a;
      res.b = op1.b+op2.b;
      
      return res;
     }
     
     public static Complex operator-(Complex op)
     {
      Complex res = new Complex();
      res.a = -op.a;
      res.b = -op.b;
      
      return res;
     }
     
     public static Complex operator-(Complex op1,Complex op2)
     {
      Complex res = new Complex();
      res.a = op1.a - op2.a;
      res.b = op1.b - op2.b;
      
      return res;
     }
     
     public static Complex operator ++(Complex op)
     {
      op.a++;
      op.b++;
      return op;
     }
     
     public static Complex operator --(Complex op)
     {
      op.a--;
      op.b--;
      return op;
     }
     
     public static Complex operator+(Complex op1,int op2)
     {
      Complex res = new Complex();
      res.a = op1.a + op2;
      res.b = op1.b + op2;
      
      return res;
     }
     
     public static Complex operator+(int op1,Complex op2)
     {
      Complex res = new Complex();
      res.a = op1 + op2.a;
      res.b = op1 + op2.b;
      
      return res;
     }
     
     public static bool operator<(Complex op1,Complex op2)
     {
      if ((op1.a<op2.a) && (op1.b<op2.b))
      return true;
      else
      return false;
     }
     
     public static bool operator>(Complex op1,Complex op2)
     {
      if ((op1.a>op2.a) && (op1.b>op2.b))
      return true;
      else
      return false;
     }
     
     public static bool operator true(Complex op)
     {
      if((op.a!=0) || (op.b!=0))
       return true;
      else
       return false;
     }
     
     public static bool operator false(Complex op)
     { 
      if((op.a==0) && (op.b==0))
       return true;
      else
       return false;
     }
     
     public static Complex operator |(Complex op1, Complex op2)
     {
      if( ((op1.a !=0) || (op1.b!=0)) | ((op2.a!=0) || (op2.b!=0)) )
       return new Complex(1,1);
      else
       return new Complex(0,0);
     }
     
     public static Complex operator &(Complex op1, Complex op2)
     {
      if( ((op1.a !=0) && (op1.b!=0)) & ((op2.a!=0) && (op2.b!=0)) )
        return new Complex(1,1);
      else
       return new Complex(0,0);
     }
     
     public static bool operator !(Complex op)
     {
      if (op) return false;
      else
       return true;
     }
     
     public static implicit operator int(Complex op)
     {
      return op.a+ op.b;
     }
     public static explicit operator string(Complex op)
     {
      string s;
      s = (op.a).ToString();
      if(op.b>=0)
      {
       s+=" + ";
       s+= (op.b).ToString();
       s+="i";
      }
      else
      {
       s+=(op.b).ToString();
       s+="i";
      }
      return s;
     }
    }
    class ComplexUse
    {
      static void Main(string[] args)
     {
       Complex obj1 = new Complex();
       Complex obj2 = new Complex(5,-2);
       Complex obj3 = new Complex(1,4);
       Complex obj4 = new Complex(1,2);
       Complex obj5 = new Complex(2,3);
       Complex obj6 = new Complex(1,6);
       Complex obj7 = new Complex(2,-2);
       Complex obj8 = new Complex(5,5);
       int i;
       string str;
       obj1.Print();
       obj2.Print();
       obj3.Print();
       obj4.Print();
       obj5.Print();
       obj6.Print();
       obj7.Print();
       obj8.Print();
       obj1 = obj2 + obj3;
       Console.Write("Результат сложения obj2 и obj3 = ");
       obj1.Print();
       
       obj1 = obj2 - obj3;
       Console.Write("Результат вычитания obj2 и obj3 = ");
       obj1.Print();
       
       obj1 = -obj2;
       Console.Write("Результат применения операции унарный минус для obj2 = ");
       obj1.Print();
       
       obj3++;
       Console.Write("Результат применения операции инкремента для obj3 = ");
       obj3.Print();
      // Console.WriteLine(obj2.b);
      
       obj1 = obj2+5;
       Console.Write("Результат сложения obj2 и числа 5 = ");
       obj1.Print();
       
       obj1 = 4+obj2;
       Console.Write("Результат сложения числа 4 и obj2 = ");
       obj1.Print();
       
       if(obj4<obj5)
        Console.WriteLine("ДА obj4 < obj5");
       else
        Console.WriteLine("НЕТ obj4 > obj5");
       
       if(obj4>obj5)
        Console.WriteLine(" ДА obj4 > obj5");
       else
        Console.WriteLine("НЕТ obj4 < obj5"); 
       
       if(obj6) 
        Console.WriteLine("obj6 - ИСТИНА");
       else
        Console.WriteLine("obj6 - ЛОЖЬ"); 
         
        if(obj7) 
        Console.WriteLine("obj7 - ИСТИНА");
       else
        Console.WriteLine("obj7 - ЛОЖЬ");
        
        do{
         obj8.Print();
         obj8--;
        } while(obj8);
        
        if(obj6 && obj7)
         Console.WriteLine("obj6 & obj7 ИСТИНА");
        else
        Console.WriteLine("obj6 & obj7 ЛОЖЬ");
        
        i = obj7;
        Console.WriteLine("Результат присваивания int переменной = " + i);
        str = (string)obj7;
        Console.WriteLine("Результат присваивания string переменной = "+ str);
       Console.ReadLine();
     }
    }
    

    28 сентября 2010 г. 11:03
  • Необходимо реализовать именно шаблон для комплексных чисел, который может хранить данные и выполнять операции, например, с обычной и двойной точностью, а не просто использовать тип переменных int и производит вычисления над целыми числами(я про int a и int b)
    28 сентября 2010 г. 11:32
  • Если коротко - то ошибка вылазит из-за вызова операторов +/ у типа-параметра шаблона. Тип параметра заранее не известен. Гарантировать, что оператор + для него будет определен - нельзя. Хуже того, нельзя даже поставить ограничение на наличее оператора + у типа Current_type.

    Есть варианты со всякой кодогенерацией. Гугл подсказывает Generic Operators и построенный на них Generic Complex Type

    • Предложено в качестве ответа PashaPash 28 сентября 2010 г. 19:23
    • Помечено в качестве ответа I.Vorontsov 30 сентября 2010 г. 12:49
    28 сентября 2010 г. 19:23