Using MVC3 and the StringLength validation attribute on a property of type MyType<string> who’s internal value is a string, I get an exception:
Unable to cast object of type ‘MyType’ to type ‘System.String’.
So I added an operator overload, here’s my class:
public class MyType<T>
{
public T Value { get; set; }
//...
public static implicit operator string(MyType<T> instance)
{
//Return the internal value of the instance.
return Convert.ToString(instance.Value);
}
}
So this should, in theory, allow MyType to be cast to a String. However, I still get the same error, here is the stack trace:
[InvalidCastException: Unable to cast object of type ‘MyType’ to type
‘System.String’.]
System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(Object
value) +64
System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object
value, ValidationContext validationContext) +176
System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object
value, ValidationContext validationContext) +41
System.Web.Mvc.d__1.MoveNext() +267
The StringLengthAttribute.IsValid method (from the .NET framework, not my code) is doing this:
public override bool IsValid(object value)
{
this.EnsureLegalLengths();
int num = (value == null) ? 0 : ((string)value).Length;
return value == null || (num >= this.MinimumLength && num <= this.MaximumLength);
}
Seems like it should work, what am I missing?
The variable
valueis declared of typeobject. You must first cast to the actual type first since the underlying object is not astring. There are no conversions defined fromobjectto other types so the cast you’re doing is effectively telling the compiler that this object is actually astringwhen it is not. This is essentially the same kind of rule that must be followed when unboxing value types.By casting it to your type first, the compiler can then realize that a (implicit) conversion exists from your type to the desired
stringtype and can generate the appropriate instructions.e.g.,