Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Перегрузка операторов

Какое знакомый мотив...

Перегрузка операторов в C# несколько отличается от перегрузки операторов в C++. Давайте разбираться с нововведениями (рассматриваем, естественно, только отличия).


*****
Все перегруженные операторы должны быть открытыми статическими функциями класса. Следовательно, унарные операторы будут иметь один параметр, а бинарные - два.
*****

Унарные операторы

Можно перегружать следующие унарные операторы: +, -, !, ~, ++, --, true, false

Как уже оговаривалось выше, перегруженные унарные операторы должны иметь один параметр. Этот параметр должен быть типа класса, в котором реализуется данная функция.

using System;

class SomeClass
{
    int i;

    public SomeClass(int value)
    {
        i = value;
    }

    public static int operator - (SomeClass s)
    {
        return -s.i;
    }
}

class Test
{
    static void Main()
    {
        SomeClass sc = new SomeClass(10);
        Console.WriteLine(-sc);
    }
}

В отличие от C++ при перегрузке операторов инкремента (++) и декремента (--), невозможно определить где постфикс, а где префикс. Поэтому при перегрузке данных операторов определены оба случая сразу.

using System;

class SomeClass
{
    int i;

    public SomeClass(int value)
    {
        i = value;
    }

    // Для операторов ++ и -- возвращаемое значение
    // также должно быть типа класса
    public static SomeClass operator ++ (SomeClass s)
    {
        ++s.i;
        return s;
    }

    public override string ToString()
    {
        return i.ToString();
    }
}

class Test
{
    static void Main()
    {
        SomeClass sc = new SomeClass(10);
        Console.WriteLine(++sc);
        Console.WriteLine(sc++);
    }
}

Перегрузка операторов true и false в основном применяется для логических типов, у которых следующие два выражения не эквивалентны:

if(a == true)

if(! (a == false))

Это характерно для типов данных SQL, обладающих неопределенным состоянием (не true и не false). В этом случае компилятор может использовать перегруженные операторы true и false для правильного вычисления результатов таких выражений (см. пример в MSDN). Эти операторы должны возвращать тип bool и перегружаться в паре (если перегружается один, то должен перегружаться и второй).

using System;

class SomeClass
{
    int i;

    public SomeClass(int value)
    {
        i = value;
    }

    public override string ToString()
    {
        return i.ToString();
    }

    public static bool operator true(SomeClass s)
    {
        return s.i != 0;
    }

    public static bool operator false(SomeClass s)
    {
        return s.i == 0;
    }
}

class Test
{
    static void Main()
    {
        SomeClass sc = new SomeClass(10);
        if(sc)
            Console.WriteLine("yes");
        else
            Console.WriteLine("no");
    }
}

Бинарные операторы

Можно перегружать следующие бинарные операторы: +, -, *, /, %, &, |, ^, <<, >>

Для данных операторов справедливы следующие правила: один из двух параметров функции должен быть типа класса; если в классе перегружен оператор + (например), то оператор += перегружается автоматически (это справедливо для всех вышеперечисленных бинарных операторов).


*****
Операторы +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= напрямую перегружать нельзя.
*****
using System;

class SomeClass
{
    int i;

    public SomeClass(int value)
    {
        i = value;
    }

    public override string ToString()
    {
        return i.ToString();
    }

    public static SomeClass operator + (SomeClass s, int ii)
    {
        s.i += ii;
        return s;
    }
}

class Test
{
    static void Main()
    {
        SomeClass sc = new SomeClass(10);
        Console.WriteLine(sc + 3);

        sc += 2;

        Console.WriteLine(sc);
    }
}

Операторы сравнения ==, !=, <, >, <=, >= всегда перегружаются парами: == и !=, < и >, <= и >=.

Чаще всего перегружаются операторы == и !=, так как по умолчанию они сравнивают не сами объекты, а ссылки на них (для ссылочных типов). В паре с этими операторами желательно перегрузить функцию Equals, которая наследуется из базового класса Object, чтобы их функциональность не различалась. Подробнее об этом вы можете узнать, изучив пример из следующего раздела.

Операторы && и || напрямую не перегружаются. Для их эмуляции можно перегрузить операторы & и | (см. пример в MSDN), которые для булевских значений возвращают также булевское значение.

Оператор [] не перегружается, вместо него можно использовать индексаторы.

Следующие операторы перегружаться не могут: =, ., ?:, ->, new, is, sizeof, typeof

Оператор () перегружаться не может, но вместо него можно определить собственные преобразования.

Неявные преобразования

Это преобразования, которые можно применять без приведения типов. Такие преобразования (желательно) не должны вызывать исключительных ситуаций и не допускать потерю информации.

Явные преобразования

Это преобразования, которые применяются с приведением типа. Такие преобразования могут вызывать исключительные ситуации и допускать потерю информации.

Пример на перегрузку явных и неявных преобразований

using System;

class SomeClass
{
    int i;

    public SomeClass(int value)
    {
        i = value;
    }

    public override string ToString()
    {
        return i.ToString();
    }
    // Неявное преобразование из SomeClass в int
    public static implicit operator int(SomeClass s)
    {
        return s.i;
    }
    // Явное преобразование из int в SomeClass
    public static explicit operator SomeClass(int ii)
    {
        SomeClass s = new SomeClass(ii);
        return s;
    }
}

class Test
{
    static void Main()
    {
        SomeClass sc = new SomeClass(10);
        // Неявное преобразование
        int i = sc;
        Console.WriteLine(i);

        // Явное преобразование
        sc = (SomeClass)100;
        Console.WriteLine(sc);
    }
}
Более подробную информацию можно получить, изучив практические 
примеры, или заглянув в MSDN.


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru