Can't Cast to String Even With Operator Overloaded
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 value
is declared of type object
. You must first cast to the actual type first since the underlying object is not a string
. There are no conversions defined from object
to other types so the cast you're doing is effectively telling the compiler that this object is actually a string
when 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 string
type and can generate the appropriate instructions.
eg,
object obj = new MyObject<string> { Value = "Foobar" };
string x = (string)obj; // fail: obj is not a string
string y = (MyObject<string>)obj; // obj: obj is cast to MyObject<string> and
// an implicit cast to string exists
// to be clearer
string z = (string)(MyObject<string>)obj;
public override bool IsValid(object value)
{
this.EnsureLegalLengths();
int num = (value == null) ? 0 : ((MyType<string>)value).Value.Length;
return value == null || (num >= this.MinimumLength && num <= this.MaximumLength);
}
Don't cast it to string
, but to MyType<string>
.
The changed line of code to reflect this is:
int num = (value == null) ? 0 : ((MyType<string>)value).Value.Length;
Edit : Don't pass MyType<string>
to the method, pass MyType<string>.Value
to it so that cast will be successful.
You are using implicit cast and you should do explicit cast because the framework cast it explicitly. Like this:
(string)value
You should add:
public static explicit operator string(MyType<T> instance)
{
//Return the internal value of the instance.
return Convert.ToString(instance.Value);
}
链接地址: http://www.djcxy.com/p/71062.html
上一篇: 使用NHibernate查询'时间'字段时无效的转换异常
下一篇: 即使运算符重载也无法强制转换为字符串