views:

161

answers:

4

Let's say you have yourself a class like the following:

public sealed class StringToInt { 
    private string _myString; 
    private StringToInt(string value) 
    { 
        _myString = value; 
    } public static implicit operator int(StringToInt obj) 
    { 
        return Convert.ToInt32(obj._myString); 
    } 
    public static implicit operator string(StringToInt obj) 
    { 
        return obj._myString; 
    } 
    public static implicit operator StringToInt(string obj) 
    { 
        return new StringToInt(obj); 
    } 
    public static implicit operator StringToInt(int obj) 
    { 
        return new StringToInt(obj.ToString()); 
    } 
}

Will you then be able to write code like the following:

MyClass.SomeMethodThatOnlyTakesAnInt(aString);

without it stating that there is no implicit cast from string to int?

[Yes, i could test it myself but i thought i would put it out there and see what all of the gurus have to say]

A: 

Typos in your snippet:

public StringToInt(string value)
{
    _myString = value;
}
public static implicit operator int(StringToInt obj)
{
    return Convert.ToInt32(obj._myString);
}
public static implicit operator string(StringToInt obj)
{
    return obj._myString;
}

If aString is of type StringToInt, your usage should work.

gWiz
Yup i caught those, but i may point out that the goal is to get an implicit cast from string to int...
RCIX
Since you can't extend the built-in types, you can't create new implicit conversions for them. Intuitively I wouldn't expect the compiler to allow this. It would seem indeterminate which classes the compiler would look at to determine a possible chain of implicit conversions. Also the readability of such code seems awful, not to mention resolving conflicts when you pass a variable to a method family that has overloads for that variable type as well as something it can implicitly be converted to.
gWiz
A: 

It does not appear to work. It requires at least one explicit cast. Oh well...

RCIX
+1  A: 

I am fairly certain this is not possible under C# 3.0. The sections in the reference that covers conversions is 6.4. Namely, 6.4.4 "User-defined implicit conversions".

It only talks about conversions from S->T (and not S->T->U) which covers the cases such as:

StringToInt _t = "foo";
int t = _t;

and

int t = (StringToInt)"foo";

Where both of these cases only involve S->T (twice).

I am pretty sure this is not possible in C# 3.0. Allowing S->T->U would require much more work to be performed by the type matcher, at least following the algorithm specified.

pst
+4  A: 

No C# won't call more than one user defined implicit conversion. From the C# spec section 6.4.3:

Evaluation of a user-defined conversion never involves more than one user-defined or lifted conversion operator. In other words, a conversion from type S to type T will never first execute a user-defined conversion from S to X and then execute a user-defined conversion from X to T.

shf301