Вопрос по .net, c# – C #: пользовательское приведение к типу значения

10

Можно ли привести пользовательский класс к типу значения?

Вот пример:

var x = new Foo();
var y = (int) x; //Does not compile 

Возможно ли, чтобы вышесказанное произошло? Нужно ли что-то перегрузить вFoo ?

Что вы ожидаете от этого? Как выглядит Foo? Henk Holterman

Ваш Ответ

5   ответов
7

Создайте явное или неявное преобразование:

public class Foo
{
    public static explicit operator int(Foo instance)
    {
        return 0;
    }

    public static implicit operator double(Foo instance)
    {
        return 0;
    }
}

Разница в том, что при явных преобразованиях вам придется самостоятельно выполнять приведение типа:

int i = (int) new Foo();

а с помощью неявных преобразований вы можете просто "назначить" вещи:

double d = new Foo();

MSDN имеет это сказать:

& quot; Исключая ненужные преобразования, неявные преобразования могут улучшить читаемость исходного кода. Однако, поскольку неявные преобразования не требуют, чтобы программисты явно приводили данные из одного типа в другой, необходимо соблюдать осторожность, чтобы предотвратить непредвиденные результаты.In general, implicit conversion operators should never throw exceptions and never lose information so that they can be used safely without the programmer's awareness. If a conversion operator cannot meet those criteria, it should be marked explicit.& Quot; (Акцент мой)

23

Вам придется перегрузить оператор приведения.

    public class Foo
    {
        public Foo( double d )
        {
            this.X = d;
        }

        public double X
        {
            get;
            private set;
        }


        public static implicit operator Foo( double d )
        {
            return new Foo (d);
        }

        public static explicit operator double( Foo f )
        {
            return f.X;
        }

    }
Отлично, именно то, что я искал в ответе. Приветствия. Andreas Grech
Можете ли вы объяснить использование неявного и явного в своем ответе? Благодарю. Andreas Grech
5

Вам нужно определитьявный или женеявный Кастинг:

public class Foo
{
    public static implicit operator int(Foo d)
    {
        return d.SomeIntProperty;
    }

    // ...
1

Я бы посоветовал вам реализовать интерфейс IConvertible, так как он предназначен для этого. Увидетьhttp://msdn.microsoft.com/en-us/library/system.iconvertible.aspx

0

Другая возможность - написать метод расширения Parse и TryParse для вашего класса.

Затем вы пишете свой код следующим образом:

var x = new Foo();
var y = int.Parse(x); 
Потому что когда у тебя молоток, каждая проблема - гвоздь.
Не Марк, Мартин предполагает, что методы расширения - это молотки. :) Проблема с методом расширения заключается в том, что вы разбрасываете логику повсюду, и что метод расширения не будет напрямую отображаться intellisense, если пространство имен, в котором определен метод расширения, не используется. Поскольку у вас есть контроль над классом foo, лучше написать метод TryParse как обычный метод-член, а не метод расширения.
@Mark: даже если вы написали метод расширения, вы не сможете использовать его с & quot; var y = int.Parse (x); & quot; потому что методы расширения применяются только к экземплярам. Вы должны сделать что-то вроде "var y = x.ParseToInt (); & quot;" вместо этого, и в этом случае, почему бы просто не поместить метод ParseToInt в сам класс, как говорит Фредерик.
почему вы пишете это как метод расширения, а не как обычный метод члена? Это его класс, так что он контролирует его.
Не зная больше о его классе Foo, я просто предложил другую возможность. @ Мартин Браун: Вы предлагаете, чтобы другие методы Try и TryParse были молотками? Нет, они соответствуют их парадигме работы со строками. Я действительно не могу вывести большую часть проблемной области. @ Фредерик: Он имеет такой же контроль над методом расширения, как и со своим собственным классом.

Похожие вопросы