C # Кастинг с операторами преобразования - PullRequest
0 голосов
/ 05 февраля 2012

У меня есть пользовательская реализация класса string. Я добавил пользовательские операторы преобразования между строкой и классом, и приведение работает нормально. Но если я сначала приведу пользовательский объект к System.Object, а затем к строке, он скажет: «Невозможно привести тип« MyString »к типу« System.String »». Это почему? Как я могу включить это ...

class MyString
{
    public string S {get; set;}

    public MyString(string s)
    {
        this.S = s;
    }

    public static implicit operator string(MyString s)
    {
        return s.S;
    }
    public static implicit operator MyString(string s)
    {
        return new MyString(s);
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyString ms = new MyString("a");
        string s = ms;
        object o = ms;
        string s1 = (string)o; // <-- this throws the exception!
    }
}

Ответы [ 2 ]

6 голосов
/ 05 февраля 2012

Преобразования, подобные этому, должны быть определены в время компиляции - тогда как в вашей последней строке тип времени компиляции o просто object, поэтому компилятор "не знает"«о вашем преобразовании в качестве опции.

Трудно найти лучшее решение вашей проблемы, кроме как просто сказать« не делайте этого »- если вы используете dynamic вместо object (и выконечно, вы используете C # 4), тогда он будет работать - но лично я бы просто попытался , а не , чтобы полагаться на определенные пользователем преобразования, подобные этому.Они делают кодовую базу очень трудной для понимания, ИМО.

Любой, кто читает выражение (string) o, где o - это просто object, будет ожидать , что это будет простое приведение, т.е.что не состоялось бы, если бы o фактически не ссылался на строку (или был нулевой ссылкой).Пытаться найти способы опровергнуть это ожидание - плохая идея, ИМО.

3 голосов
/ 05 февраля 2012

Я бы переопределил ToString в вашем классе.А затем используйте o.ToString() вместо (string)o.

...