如何在c#中创建显式的自定义强制转换?

e-i*_*128 1 .net c# casting

有这个代码:

string abc = "123456";
Run Code Online (Sandbox Code Playgroud)

要转换为int,我应该使用convert:

int abcInt = Convert.ToInt32(abc);
Run Code Online (Sandbox Code Playgroud)

问题是,如果不是数字我有一个例外,看到返回零,所以我的最终代码将如下所示:

try{ int abcInt = Convert.ToInt32(abc); }catch(Exception e){ int abcInt = 0; }
Run Code Online (Sandbox Code Playgroud)

所以你看到我决定创建一本书,使我成为一个返回零数字的对象,如果失败则无异常,因此可以在没有太多垃圾代码的情况下保持最灵活的编程:

int abcInt = Libs.str.safeInt(abc);
Run Code Online (Sandbox Code Playgroud)

代码是:

public int safeInt(object ob)
{
    if ((ob == null) || (String.IsNullOrEmpty(ob.ToString())))
        return 0;
    try
    {
        return Convert.ToInt32(
            System.Text.RegularExpressions.Regex.Replace(ob.ToString(), @"@[^Ee0-9\.\,]+@i", "").
            ToString(CultureInfo.InvariantCulture.NumberFormat)
        );
    }
    catch (FormatException e)
    {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

但我想更进一步,做这样的事情:

int abcInt = (safeInt)abc;
Run Code Online (Sandbox Code Playgroud)

怎么做?

无法将'string'类型转换为'Libs.safeInt.safeInt'

jas*_*son 5

应该使用Int32.TryParse:

int abcInt;
if(!Int32.TryParse(abc, out abcInt)) {
    abcInt = 0;
}
// abcInt has been parsed to an int, or defaulted to zero
Run Code Online (Sandbox Code Playgroud)

请注意,这可以缩短为

int abcInt;
Int32.TryParse(abc, out abcInt);
Run Code Online (Sandbox Code Playgroud)

如果你想要的只是默认值为零,因为:

当此方法返回时s,如果转换成功,则包含等于包含的数字的32位有符号整数值,如果转换失败,则包含.如果s参数是null,格式不正确,或者表示小于MinValue或大于的数字,则转换失败MaxValue.此参数未初始化传递.

我实际上建议不要这样写,因为现在你无法区分abc = "0"abc = "garbage"; 两者都表现出与上面两行代码完全相同的行为.使用上面的初始版本(即,如果需要if,可以区分这两种情况;默默地忽略错误通常是一个主意).

这就是说,如果你绝对是极想知道如何实现一个explicit转换运算符,你这样进行:

class SafeInt32 {
    private readonly int value;
    public int Value { get { return this.value; } }

    private readonly string source;
    public string Source { get { return this.source; } }

    private readonly bool successful;
    public bool Successful { get { return this.successful; } }

    public SafeInt32(string source) {
        this.source = source;
        this.successful = Int32.TryParse(source, out this.value);
    }

    public static explicit operator SafeInt32(string source) {
        return new SafeInt32(source);
    }

    public static implicit operator int(SafeInt32 safeInt32) {
        return safeInt32.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

int abcInt = (SafeInt32)"123456";
Run Code Online (Sandbox Code Playgroud)

请注意,我们必须定义一个明确的类型转换操作符投下stringSafeInt32,和隐式类型转换操作符投下SafeInt32一个int实现你想要的语法.后者是必要的,以便编译器可以静默转换的结果(SafeInt32)"123456"到一个int.

我再次建议要这样做; 用Int32.TryParse.