explicit (Справочник по C#)

Ключевое слово explicit служит для объявления оператора преобразования пользовательского типа, который следует вызывать во время приведения. Например, следующий оператор выполняет преобразование из класса Fahrenheit в класс Celsius.

// Must be defined inside a class called Fahrenheit: 
public static explicit operator Celsius(Fahrenheit fahr)
{
    return new Celsius((5.0f / 9.0f) * (fahr.degrees - 32));
}

Такой оператор можно вызвать следующим образом.

Fahrenheit fahr = new Fahrenheit(100.0f);
Console.Write("{0} Fahrenheit", fahr.Degrees);
Celsius c = (Celsius)fahr;

Оператор преобразования выполняет преобразование из исходного типа в тип назначения. Оператор преобразования предоставляется исходным типом. В отличие от неявного преобразования операторы явного преобразования вызываются с помощью приведения. Если операция преобразования может вызвать исключения или потерю информации, необходимо пометить ее ключевым словом explicit. Это позволит избежать скрытого вызова компилятором операции преобразования, которая может привести к непредсказуемым последствиям.

Если приведение пропустить, произойдет ошибка времени компиляции CS0266.

Дополнительные сведения см. в разделе Использование операторов преобразования (Руководство по программированию в C#).

Пример

В следующем примере показаны классы Fahrenheit и Celsius, в каждом из которых определен оператор явного преобразования в другой класс.

class Celsius
{
    public Celsius(float temp)
    {
        degrees = temp;
    }
    public static explicit operator Fahrenheit(Celsius c)
    {
        return new Fahrenheit((9.0f / 5.0f) * c.degrees + 32);
    }
    public float Degrees
    {
        get { return degrees; }
    }
    private float degrees;
}

class Fahrenheit
{
    public Fahrenheit(float temp)
    {
        degrees = temp;
    }
    // Must be defined inside a class called Fahrenheit: 
    public static explicit operator Celsius(Fahrenheit fahr)
    {
        return new Celsius((5.0f / 9.0f) * (fahr.degrees - 32));
    }
    public float Degrees
    {
        get { return degrees; }
    }
    private float degrees;
}

class MainClass
{
    static void Main()
    {
        Fahrenheit fahr = new Fahrenheit(100.0f);
        Console.Write("{0} Fahrenheit", fahr.Degrees);
        Celsius c = (Celsius)fahr;

        Console.Write(" = {0} Celsius", c.Degrees);
        Fahrenheit fahr2 = (Fahrenheit)c;
        Console.WriteLine(" = {0} Fahrenheit", fahr2.Degrees);
    }
}
// Output: 
// 100 Fahrenheit = 37.77778 Celsius = 100 Fahrenheit

В следующем примере определена структура Digit, представляющая один разряд. Для преобразования типа byte в тип Digit определен оператор, но поскольку не все значения типа byte можно преобразовать в Digit, преобразование выполняется явным образом.

struct Digit
{
    byte value;
    public Digit(byte value)
    {
        if (value > 9)
        {
            throw new ArgumentException();
        }
        this.value = value;
    }

    // Define explicit byte-to-Digit conversion operator: 
    public static explicit operator Digit(byte b)
    {
        Digit d = new Digit(b);
        Console.WriteLine("conversion occurred");
        return d;
    }
}

class ExplicitTest
{
    static void Main()
    {
        try
        {
            byte b = 3;
            Digit d = (Digit)b; // explicit conversion
        }
        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
/*
Output:
conversion occurred
*/

Спецификация языка C#

Дополнительные сведения см. в Спецификация языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

См. также

Задачи

Практическое руководство. Реализация определенных пользователем преобразований между структурами (Руководство по программированию на C#)

Ссылки

Ключевые слова C#

implicit (Справочник по C#)

operator (Справочник по C#)

Основные понятия

Руководство по программированию на C#

Другие ресурсы

Справочник по C#

Определяемые пользователем цепного явные преобразования в C#