2013-03-22 51 views
2

我是linq的新手,并且这会在空卷字段上弹出。该文件是不可预知的,它会发生,所以我想在出现异常的地方设置0。任何快速简单的方法来做到这一点?在Linq中处理null

 var qry = 
      from line in File.ReadAllLines("C:\\temp\\T.txt") 
      let myRecX = line.Split(',') 
      select new myRec() 

      { 

       price = Convert.ToDecimal(myRecX[0].Replace("price = ", "")) , 
       volume = Convert.ToInt32(myRecX[1].Replace("volume =", "")), 
       dTime = Convert.ToDateTime(myRecX[2].Replace("timestamp =", "")) 

      }; 
+0

我会考虑使用正则表达式来代替。 – 2013-03-22 18:16:57

+1

你是否得到一个空引用异常或数组索引超出界限异常? – 2013-03-22 18:17:12

+0

*“我想在出现异常的地方放一个0”* - 这看起来不是个好主意?你为什么更喜欢*错误的数据*? – cdhowie 2013-03-22 18:17:55

回答

4

如果您想使用默认时传入的数据是null,空,或完全由空白字符,你可以做这样的:

volume = string.IsNullOrWhitesplace(myRecX[1]) 
     ? defaultVolume // <<== You can use any constant here 
     : Convert.ToInt32(myRecX[1].Replace("volume =", "")) 

然而,这是一个“快速和肮脏”的方式来实现你所需要的,因为每个命名参数的位置保持硬编码。更可靠的方法是编写一个迷你分析器,注意文件中指定的属性名称,而不是用空字符串替换它们。

+0

美丽的,我不得不添加替换功能,两个比较,但工作像一个魅力音量= string.IsNullOrWhiteSpace(myRecX [1] .Replace(“音量=”,“”)) ? 0 // << ==你可以在这里使用任何常量 :Convert.ToInt32(myRecX [1] .Replace(“volume =”,“”)), – DotNetDudeinDC 2013-03-22 18:33:37

0

你可以使用这样的事情,它提供了一个表达方式来写你想要什么:

static TOutput Convert<TInput, TOutput>(
    TInput value, 
    params Func<TInput, TOutput>[] options) 
{ 
    foreach (var option in options) { 
     try { return option(value); } 
     catch { } 
    } 

    throw new InvalidOperationException("No option succeeded."); 
} 

使用,如:

select new myRec() 
{ 
    price = Convert(myRecX[0].Replace("price = ", ""), 
        input => Convert.ToDecimal(input), 
        or => 0M), 
    ... 
}; 

功能间接和含蓄阵列结构可能会产生轻微的性能会受到损失,但它为您提供了一种很好的语法,用于指定一些可能的转换,其中第一个获得成功。

0

我想这里有一个超出使用Linq的问题。

一般来说,在处理文件数据之前操作文件数据是不好的做法。

自从如果以下问题是关于文件名(而不是它的内容)是一个很好的起点,了解概念消毒输入

C# Sanitize File Name

所有自己告诉你的代码后缺少文件内容的控制,使呼叫前:

let myRecX = line.Split(',')

我建议定义一个公开并购方法如:

string SanitizeInputLine(string input) { 
    // here do whatever is needed to bring back input to 
    // a valid format in a way that subsequent calls will not 
    // fail 

    return input; 
} 

应用它很简单;

let myRecX = SanitizeInputLine(line).Split(',')

作为一般规则永远不要相信输入。

我引述第10章名为_All输入是邪恶__的Writing Secure Code霍华德/勒布朗:

...你永远不应该信任的数据,直到数据被验证。未能做到 这样会使您的应用程序易受攻击。或换句话说:全部 输入是邪恶的,直到证明