Автоматическое преобразование типов в С#

Я знаю, что вы можете переопределить метод Object ToString(), чтобы каждый раз, когда вы вызывали объект или передавали его функции, которая требует типа String, она будет преобразована в строку.

Я написал несколько методов расширения для типа объекта "объект"

public static DateTime ToDate(this object date)
{
    return DateTime.Parse(date.ToString());
}

public static int ToInteger(this object num)
{
    return Int32.Parse(num.ToString());
}

public static long ToLong(this object num)
{
    return Int64.Parse(num.ToString());
}

чтобы я мог просто называть их следующим образом:

eventObject.Cost = row["cost"].ToString();
eventObject.EventId = row["event_id"].ToLong();

Однако, что я хочу сделать, это преобразовать объекты строк, которые имеют тип "объект", в его правильный тип, основанный на типах свойств в моем "eventObject". Поэтому я мог бы назвать это следующим образом:

eventObject.Cost = row["cost"];
eventObject.EventId = row["event_id"];

Строка - это DataRow, если это имеет значение.

Ответ 1

С# поддерживает неявное преобразование для типов, и вы можете использовать его для своих пользовательских типов, таких как:

 class CustomValue
 {
     public static implicit operator int(CustomValue v)  {  return 4;  }

     public static implicit operator float(CustomValue v) {  return 4.6f;  }
 }

 class Program
 {
     static void Main(string[] args)
     {
         int x = new CustomValue(); // implicit conversion 
         float xx = new CustomValue(); // implicit conversion 
     }
 }

И поддерживает методы расширения, но не поддерживает неявное преобразование в качестве метода расширения, такого как:

static class MyExtension
{
    // Not supported
    public static implicit operator bool(this CustomValue v)
    {
        return false;
    }
}

Ответ 2

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

Нет, вы ошибаетесь. Следующий код не будет компилироваться:

class MyClass
{
    public override string ToString()
    {
        return "MyClass";
    }
}

static void MyMethod(string s) { }

static void Main(string[] args)
{
    MyMethod(new MyClass());   //compile error
}

Компилятор не получит тип MyMethod (который является string) первым и попытается преобразовать переданный вами аргумент (тип которого MyClass). Наверное, вы, вероятно, обманываете что-то вроде Console.WriteLine. Основываясь на приведенном выше коде, Console.WriteLine(new MyClass()) печатает "MyClass" на консоли, кажется, что компилятор знает, что вы должны передать строку в Console.WriteLine и попытаться преобразовать MyClass в строку. Но существенным является Console.WriteLine имеет несколько перегрузок, один из которых для object:

//from Console.cs
public static void WriteLine(object value)
{
    //in this method there is something like
    //Console.WriteLine(value.ToString());
}

Ответ 3

Я считаю, что вы ищете неявное преобразование, которое описано здесь: http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx.

Однако добавление их в объект будет очень плохой идеей по причинам, указанным на странице, с которой я связан.

Ответ 4

Простите меня, если я выскажу очевидное, но у меня сложилось такое впечатление после прочтения вашего вопроса.

Знаете ли вы, что базовый тип каждого типа в .NET является объектным? Таким образом, столбец в datarow, который вы описываете для объекта типа, также может быть того же типа, что и член, который вы пытаетесь назначить, и затем требуется простое копирование.

например

eventObject.EventId = (int) строка [ "event_id" ];

Ответ 5

Подводя итог - просто определите эти методы, и вы можете использовать объекты класса Test в методах, требующих String в качестве параметра.

class Test
{
    private String txt;

    public static implicit operator string(Test t)
    {
        return t.ToString();
    }

    public override string ToString() 
    {
        return txt;
    }
}