简体   繁体   中英

Automatic type Conversion in C#

I know that you could override an object's ToString() Method, so that everytime you call an object or pass it to a function that requires a String type it will be converted to a String.

I have written several extension methods for object type 'object'

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());
}

so that I could just call them like this:

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

However, what I want to accomplish is to convert the row objects which is of type 'object' to its correct type based on the property types on my 'eventObject'. So, I could call it like this:

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

The row is a DataRow if that matters.

C# supports implicit conversion for types and you can use it for your custom types like the following:

 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 
     }
 }

And supports extension methods , but doesn't support implicit conversion as an extension method like the following:

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

I know that you could override an object's ToString() Method, so that everytime you call an object or pass it to a function that requires a String type it will be converted to a String.

No, you are wrong. The following code won't compile:

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

static void MyMethod(string s) { }

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

The compiler will not get the type of MyMethod parameter(which is string ) first and try to convert the argument you passed(whose type is MyClass ) to it. I guess you are probably mislead by something like Console.WriteLine . Base on the code above, Console.WriteLine(new MyClass()) prints "MyClass" to the console, it seems that the compiler knows you should pass a string to Console.WriteLine and try to convert MyClass to string. But the essential is Console.WriteLine has several overloads, one of them is for object :

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

I believe what you're looking for is implicit conversion, which is described here: http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx .

However, adding these to object would be a very bad idea, for reasons outlined on the page I've linked to.

To sum up - just define these methods and you can use objects of class Test in methods requiring String as a parameter.

class Test
{
    private String txt;

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

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

Forgive me if I'm stating the obvious but I got this impression after reading your question.

You know the basetype of every type in .NET is object right? So the column in the datarow which you describe of type object could also just as well be of the same type as the member you're trying to assign to and then a simple cast is needed.

for instance

eventObject.EventId = (int)row["event_id"];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM