字符串连接与三元运算符

时间:2012-12-04 22:37:43

标签: c# asp.net-mvc

我正在创建SelectList各种联系人。我希望显示的文字是FirstNameMiddleInit(如果可能)和LastName的组合。

IEnumerable<SelectListItem> items = contacts
.Select(r => new SelectListItem()
{
    Value = r.ContactID.ToString(),
    Text = r.FirstName + " " 
    + string.IsNullOrEmpty(r.MiddleInit) ? r.MiddleInit + ". " : ""
    + r.LastName
});

我收到错误:

Error   4   Cannot implicitly convert type 'string' to 'bool'   C:\Users\cu551d\Documents\Visual Studio 2010\Projects\WVM\WVM\Controllers\SOWController.cs  181 15  WVM

我猜这与我的语法有关。我可以在c#中做这样的事吗?

另外,我应该在Trim()上添加MiddleInit声明吗?我认为这个错误非常奇怪,因为IsNullOrEmpty确实会返回一个bool。我也试过(string.IsNullOrEmpty(r.MiddleInit) == true ) ..

4 个答案:

答案 0 :(得分:18)

尝试在括号中分组。它看起来像你正在向后做条件运算符:

IEnumerable<SelectListItem> items = contacts
.Select(r => new SelectListItem()
{
    Value = r.ContactID.ToString(),
    Text = r.FirstName + " " +
        (string.IsNullOrEmpty(r.MiddleInit) ? "" : (r.MiddleInit + ". ")) +
        r.LastName
});

另一种技术

因为无论如何你要将它转换为空字符串,你也可以考虑这个:

Text = r.FirstName + " " + (r.MiddleInit ?? "") + r.LastName

??被称为Null Coalescing Operator。如果该值不为null,它将返回左侧的任何内容,否则右侧的内容将返回。

http://msdn.microsoft.com/en-us/library/ms173224.aspx

编辑:虽然更清洁,但这对你的情况不太适用,因为你需要在初始之后的时期。但请注意它确实存在!

答案 1 :(得分:7)

问题是由于运算符优先级导致编译器以您不期望的方式解析表达式。只需将三元表达式包含在parens中,就会礼貌地向编译器解释你的意思。

作为旁注,看一下表达式的逻辑,我认为结果术语的顺序是不正确的。我在下面的代码中切换了它们。

IEnumerable<SelectListItem> items = contacts
.Select(r => new SelectListItem()
{
    Value = r.ContactID.ToString(),
    Text = r.FirstName + " " 
    + (string.IsNullOrEmpty(r.MiddleInit) ? "" : r.MiddleInit + ". ")
    + r.LastName
});

更多解释

如果没有(+的优先级高于?:,那么您的问题中的表达式就会被解析,就好像它说:

Test = (r.FirstName + " " + string.IsNullOrEmpty(r.MiddleInit)) ? (r.MiddleInit + ". ") : ("" + r.LastName)

因此,您的错误来源是?:运算符的条件部分实际上是一个字符串 - 其中包含类似“Andrew true”的内容。另请注意,r.LastName会与?:运算符的第三项结合使用。

修剪()问题

如果r.MiddleInit可能包含空格,那么使用Trim()会有所帮助,但最好将测试更改为String.IsNullOrWhiteSpace(r.MiddleInit)

答案 2 :(得分:1)

尝试在三元组中包装你的参数

IEnumerable<SelectListItem> items = contacts
.Select(r => new SelectListItem()
{
    Value = r.ContactID.ToString(),
    Text = r.FirstName + " " 
    + (string.IsNullOrEmpty(r.MiddleInit) ? (r.MiddleInit + ". ") : ("" + r.LastName))
});

答案 3 :(得分:1)

你不需要包装参数,只需要三元组......

IEnumerable<SelectListItem> items = contacts
.Select(r => new SelectListItem()
{
    Value = r.ContactID.ToString(),
    Text = r.FirstName + " " 
    + (string.IsNullOrEmpty(r.MiddleInit) ? r.MiddleInit + ". " : "")
    + r.LastName
});

通过尝试我发现我确实需要......

(!string.IsNullOrEmpty(r.MiddleInit) ? r.MiddleInit + ". " : "")

让它正常工作。