简体   繁体   English

LINQ:Null 检查 string.Format()

[英]LINQ: Null checking in string.Format()

I have a requirement to get the first letter of the first, middle and last names.我需要获取名字、中间名和姓氏的第一个字母。 It is working if each of the fields contain value.如果每个字段都包含值,则它正在工作。 But the middle name is nullable field.但中间名是可为空的字段。 So i'm getting error if the value of middle name is null.因此,如果中间名的值为 null,我会收到错误消息。

(from P in this._dbContext.Person
                     where P.PersonIndex == personIndex
                     select new PersonInitialsDTO
                     {
                         PersonIndex = P.PersonIndex,
                         PersonInitials = string.Format("{0}{1}{2}", P.FirstName.ToUpper().First(), P.MiddleName.ToUpper().First(), P.LastName.ToUpper().First())
                     }).FirstOrDefault();      

use ?使用? to see if the value is null before executing next methods.在执行下一个方法之前查看该值是否为 null。

string.Format("{0}{1}{2}", P.FirstName.ToUpper().First(), P.MiddleName?.ToUpper().First(), P.LastName.ToUpper().First())

P.MiddleName?.ToUpper().First() -> If P.MiddleName is null, dont do ToUpper() or any other methods afterwards. P.MiddleName?.ToUpper().First() -> 如果P.MiddleName是 null,之后不要执行 ToUpper() 或任何其他方法。


Example of use of?.的使用示例? in string.format statement .在 string.format 语句中

Pers person = new Pers()
{
    First = "First",
    Last = "Last"
};
Console.WriteLine(string.Format("{0}{1}{2}", person.First.First(), person.Middle?.ToUpper().First(), person.Last.First()));

// Prints
FL

Requirement : get the first letter of the first, middle and last names.要求:获取名字、中间名和姓氏的第一个字母。

Well, apparently this requirement is not complete: if one of these names is null or empty, there is no first letter.好吧,显然这个要求并不完整:如果其中一个名称是 null 或为空,则没有第一个字母。

Furthermore: if I look at the code, you don't want the first letter, you want a string that contains the first letter.此外:如果我查看代码,您不需要第一个字母,而是需要一个包含第一个字母的字符串。

And why uppercase the complete string if you will only use the first character?如果您只使用第一个字符,为什么要将完整的字符串大写?

So let's change it slightly:所以让我们稍微改变一下:

Requirement : Given three strings: first, middle and last, get me the string that contains the uppercase values of the first character of each of these strings, or String.Empty if the string is null or empty.要求:给定三个字符串:first、middle 和 last,给我包含每个字符串的第一个字符的大写值的字符串,或者 String.Empty,如果字符串是 null 或空。

  • "Vincent" "van" "Gogh" => "VVG" “文森特”“凡”“高”=>“VVG”
  • "rembrandt" "van" "rijn" => "RVR" “伦勃朗”“面包车”“rijn”=>“RVR”
  • "Piet" "Mondriaan" => "PM" “皮特”“蒙德里安”=>“下午”

From each of these three strings,从这三个字符串中的每一个,

  • Check if if it is null, if so, use Enumerable.Empty<char>检查是否是null,如果是,使用Enumerable.Empty<char>
  • Create a sequence that contains only the first character of the string.创建一个仅包含字符串第一个字符的序列。 So if the string was null or empty, this first character will be an empty sequence of character).因此,如果字符串是 null 或为空,则第一个字符将是一个空字符序列)。
  • Concatenate these three sequences.连接这三个序列。

Result: a sequence of characters that contains only the first character of each of these strings, or no character at all if the string was null or empty.结果:仅包含每个字符串的第一个字符的字符序列,如果字符串为 null 或为空,则根本不包含字符。

In baby steps, I'll write the type in front, so you can see what happens.在小步骤中,我会在前面写出类型,这样你就可以看到会发生什么。

string first = ...
string middle = ...
string last = ...
IEnumerable<char> firstChars = first?.Take(1) ?? Enumerable.Empty<char>(),
IEnumerable<char> midChars = middle?.Take(1) ?? Enumerable.Empty<char>(),
IEnumerable<char> lastChars = last?.Take(1) ?? Enumerable.Empty<char>(),
IEnumerable<char> chars = firstChars.Concat(midChars).Concat(lastChars);

So from our original input examples we have:因此,从我们最初的输入示例中,我们有:

  • Vincent Van Gogh: {'V', 'V', 'G'}文森特梵高:{'V', 'V', 'G'}
  • rembrandt van rijn: {'r', 'v', 'r'} rembrandt van rijn: {'r', 'v', 'r'}
  • Piet Mondriaan {'p', 'm'}皮特·蒙德里安 {'p', 'm'}

So all we have to do is to convert them to uppercase and convert to a string:所以我们要做的就是将它们转换为大写并转换为字符串:

IEnumerable uppercaseChars = chars.Select(c => Char.ToUpper(c)); IEnumerable uppercaseChars = chars.Select(c => Char.ToUpper(c));

Note: until know the query is not executed!注意:直到知道查询没有被执行! I only used methods that use deferred execution!我只使用了使用延迟执行的方法!

string result = new string(uppercaseChars.ToArray());字符串结果 = 新字符串(大写字符。ToArray());

Of course you can write this in one big LINQ statement.当然,您可以将其写在一个大的 LINQ 语句中。 I'm not sure if that would improve readability.我不确定这是否会提高可读性。 It won't have any effect on performance.它不会对性能产生任何影响。

I tried with below.我试过下面。 Now it's working现在它正在工作

(from P in this._dbContext.Person
    where P.PersonIndex == personIndex
    select new PersonInitialsDTO
    {
        PersonIndex = P.PersonIndex,
        PersonInitials = (P.MiddleName == "") 
            ? string.Format("{0}{1}", P.FirstName.ToUpper().First(), 
                P.LastName.ToUpper().First()) 
            : string.Format("{0}{1}{2}", P.FirstName.ToUpper().First(), 
                P.MiddleName.ToUpper().First(), P.LastName.ToUpper().First())
    }).FirstOrDefault();   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM