即使运算符重载也无法转换为字符串

发布于 2025-01-05 23:28:04 字数 1430 浏览 1 评论 0原文

在内部值为 stringMyType 类型的属性上使用 MVC3 和 StringLength 验证属性,我得到一个异常:

无法将“MyType”类型的对象转换为“System.String”类型。

所以我添加了一个运算符重载,这是我的类:

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

因此,理论上,这应该允许将 MyType 转换为 String。但是,我仍然遇到同样的错误,这是堆栈跟踪:

[InvalidCastException:无法将“MyType”类型的对象转换为类型 'System.String'。]
System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(对象 值)+64
System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(对象 值,ValidationContext 验证上下文)+176
System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(对象 值,ValidationContext 验证上下文)+41
System.Web.Mvc.d__1.MoveNext() +267

StringLengthAttribute.IsValid 方法(来自.NET框架,而不是我的代码)正在执行此操作:

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

看起来应该可以工作,我缺少什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请叫√我孤独 2025-01-12 23:28:04

变量value 被声明为object 类型。您必须首先转换为实际类型,因为底层对象不是字符串。没有定义从 object 到其他类型的转换,因此您所做的转换实际上是告诉编译器该对象实际上是 string,而实际上它不是。这本质上与拆箱值类型时必须遵循的规则相同。

通过首先将其转换为您的类型,编译器可以意识到存在从您的类型到所需的 string 类型的(隐式)转换,并可以生成适当的指令。

例如,

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;

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.

e.g.,

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;
初见你 2025-01-12 23:28:04
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);
}

不要将其转换为 string,而是转换为 MyType

反映这一点的更改后的代码行是:

    int num = (value == null) ? 0 : ((MyType<string>)value).Value.Length;

编辑:不要将 MyType 传递给方法,而是传递 MyType.Value 到它以便强制转换会成功。

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.

落日海湾 2025-01-12 23:28:04

您正在使用隐式强制转换,并且应该执行显式强制转换,因为框架显式强制转换它。像这样:

(string)value

您应该添加:

public static explicit operator string(MyType<T> instance)
{
    //Return the internal value of the instance.
    return Convert.ToString(instance.Value);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文