如何将 int.TryParse 与可为空的 int 一起使用? [复制]

Posted

技术标签:

【中文标题】如何将 int.TryParse 与可为空的 int 一起使用? [复制]【英文标题】:How to use int.TryParse with nullable int? [duplicate] 【发布时间】:2011-03-24 09:00:33 【问题描述】:

我正在尝试使用 TryParse 来查找字符串值是否为整数。如果该值为整数,则跳过 foreach 循环。这是我的代码。

string strValue = "42 "

 if (int.TryParse(trim(strValue) , intVal)) == false
 
    break;
 

intVal 是 int?(可为空的 INT)类型的变量。如何将 Tryparse 与可为空的 int 一起使用?

【问题讨论】:

【参考方案1】:

这是一个使用 TryParse 的可空 int 选项

public int? TryParseNullable(string val)

    int outValue;
    return int.TryParse(val, out outValue) ? (int?)outValue : null;

【讨论】:

我喜欢这个版本,因为“0”返回 0,“hello”返回 null。在接受的答案中,区别消失了。 我不喜欢他的回答,因为它丢失了表示解析成功/失败的返回值。这是 Try* 方法的一个重要特性。 @frattaro 我真的不明白为什么这个答案可能不好。尝试解析失败时默认返回 0,在此示例中它只是返回 null。 有了C#7就更简单了,不需要函数,一行就够了:int? myVal = int.TryParse(toCheck, out int tmp) ? (int?)tmp : null; @frattaro 这有一个指示解析失败 - null。【参考方案2】:

很遗憾,如果不使用另一个变量,您将无法做到这一点 - 因为 out 参数的类型必须与参数完全匹配。

类似于 Daniel 的代码,但在第二个参数、修剪和避免与布尔常量比较方面进行了固定:

int tmp;
if (!int.TryParse(strValue.Trim(), out tmp))

    break;

intVal = tmp;

【讨论】:

@JonSkeet - strValue 可以为 null 并且 Trim() 方法会导致异常。只是说。 :) @ShaktiPrakashSingh:我们不知道strValue 是否可以为空。如果它来自文本框,它可能不能为空。我的代码没有尝试解决这个问题,但我们真的不知道它是否应该解决它。 为什么不反转if?例如:if (int.TryParse(Request["idParent"], out tmp)) idParent = tmp;(否则为空) @JonSkeet 值得注意的是,我认为,虽然您的代码与提问者所要求的完全匹配(因为它很可能是关于循环/中断条件),但如果有人试图天真地在非-loop 场景在 strValue 无法解析为 int 的情况下,它们最终会以 0 作为 intVal 而不是 null。当然,你不应该仅仅因为一个答案被接受就从互联网上复制/粘贴^_^。 使用 c#7 是一行:int? myVal = int.TryParse(toCheck, out int tmp) ? (int?)tmp : null;【参考方案3】:

无法阻止自己制作通用版本。用法如下。

    public class NullableHelper
    
        public delegate bool TryDelegate<T>(string s, out T result);

        public static bool TryParseNullable<T>(string s, out T? result, TryDelegate<T> tryDelegate) where T : struct
        
            if (s == null)
            
                result = null;
                return true;
            

            T temp;
            bool success = tryDelegate(s, out temp);
            result = temp;
            return success;
        

        public static T? ParseNullable<T>(string s, TryDelegate<T> tryDelegate) where T : struct
        
            if (s == null)
            
                return null;
            

            T temp;
            return tryDelegate(s, out temp)
                       ? (T?)temp
                       : null;
         
    


bool? answer = NullableHelper.ParseNullable<bool>(answerAsString, Boolean.TryParse);

【讨论】:

【参考方案4】:

您可以创建一个辅助方法来解析可为空的值。

示例用法:

int? intVal;
if( !NullableInt.TryParse( "42", out intVal ) )

    break;

辅助方法:

public static class NullableInt

    public static bool TryParse( string text, out int? outValue )
    
        int parsedValue;
        bool success = int.TryParse( text, out parsedValue );
        outValue = success ? (int?)parsedValue : null;
        return success;
    

【讨论】:

【参考方案5】:

您也可以为此目的制作扩展方法;

public static bool TryParse(this object value, out int? parsed)

    parsed = null;
    try
    
        if (value == null)
            return true;

        int parsedValue;
        parsed = int.TryParse(value.ToString(), out parsedValue) ? (int?)parsedValue : null;
        return true;
    
    catch (Exception)
    
        return false;
    

我在object 类型上做了一个扩展,但它同样可以在string 上。就我个人而言,我喜欢这些解析器扩展可在任何对象上使用,因此扩展名为 object 而不是 string

使用示例:

[TestCase("1", 1)]
[TestCase("0", 0)]
[TestCase("-1", -1)]
[TestCase("2147483647", int.MaxValue)]
[TestCase("2147483648", null)]
[TestCase("-2147483648", int.MinValue)]
[TestCase("-2147483649", null)]
[TestCase("1.2", null)]
[TestCase("1 1", null)]
[TestCase("", null)]
[TestCase(null, null)]
[TestCase("not an int value", null)]
public void Should_parse_input_as_nullable_int(object input, int? expectedResult)

    int? parsedValue;

    bool parsingWasSuccessfull = input.TryParse(out parsedValue);

    Assert.That(parsingWasSuccessfull);
    Assert.That(parsedValue, Is.EqualTo(expectedResult));

不利的一面是这会破坏用于解析值的框架语法;

int.TryParse(input, out output))

但我喜欢它的较短版本(是否更具可读性可能需要讨论);

input.TryParse(out output)

【讨论】:

如果您这样做,您将被锁定到TryParse,仅限intdouble 呢?还是bool @FMM 有点晚了,但是,如果你想要的话,可以为它们编写一个单独的扩展方法。不确定您的意思是“锁定”其他扩展方法会有不同的签名 T 对于结构可以隐式转换为 T?。这是矫枉过正。

以上是关于如何将 int.TryParse 与可为空的 int 一起使用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Django unique_together 与可为空的 ForeignKey

如何将字符串解析为可为空的 int

如何将 C# 可为空的 int 转换为 int

如何将 CheckBox 绑定到可为空的布尔类型 DbColumn?

如何使用 ToString() 格式化可为空的 DateTime?

如何在 VB.NET 中将可为空的 DateTime 设置为空?