在C#6之前,我会编写代码来处理像这样的对象:
if (_odbcConnection != null)
{
_odbcConnection.Close();
_odbcConnection.Dispose();
_odbcConnection = null;
}
Run Code Online (Sandbox Code Playgroud)
有了6,我可以编写更少的代码:
_odbcConnection?.Close();
_odbcConnection?.Dispose();
_odbcConnection = null;
Run Code Online (Sandbox Code Playgroud)
但这两个是等价的吗?
我目前正在处理一些线程敏感代码。
在我的代码中,我有一个由两个不同线程操纵的对象的列表。一个线程可以将对象添加到此列表,而另一个线程可以将其设置为null。
在上面的参考中,它特别提到了代表:
myDelegate?.Invoke()
Run Code Online (Sandbox Code Playgroud)
等效于:
var handler = myDelegate;
if (handler != null)
{
handler(…);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这种行为与a相同List<>吗?例如:
是:
var myList = new List<object>();
myList?.Add(new object());
Run Code Online (Sandbox Code Playgroud)
保证等同于:
var myList = new List<object>();
var tempList = myList;
if (tempList != null)
{
tempList.Add(new object());
}
Run Code Online (Sandbox Code Playgroud)
?
编辑:
请注意,两者之间(代理的工作方式)有所不同:
var myList = new List<int>();
var tempList = myList;
if (tempList != null)
{
myList = null; // another thread sets myList to null here
tempList.Add(1); // doesn't crash
}
Run Code Online (Sandbox Code Playgroud)
和 …
我正在尝试执行LINQ to objects查询,如下所示:
var c1 = allCustomers
.Where(x => x.CompanyName.Replace("'", "").StartsWith(searchText))
.ToList();
Run Code Online (Sandbox Code Playgroud)
只要CompanyName不为null,这就可以正常工作.
所以,我认为这似乎是新的null条件运算符的理想位置!只需改为:
var c1 = allCustomers
.Where(x => x.CompanyName?.Replace("'", "").StartsWith(searchText))
.ToList();
Run Code Online (Sandbox Code Playgroud)
一切都应该有效!
相反,我得到错误:
Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)
Run Code Online (Sandbox Code Playgroud)
我不太确定如何在这里完成我想要的东西.在这种情况下,我如何使用null条件?
我有一个bool像这样的变量:
bool myBool = true;
Run Code Online (Sandbox Code Playgroud)
如果我写,if (myBool == null)我得到以下警告:
表达式的结果总是"假",因为类型'bool'的值永远不等于'bool?'类型的'null'.
这对我来说很清楚,因为检查一个不可为空的变量是否为空是没有意义的.Visual Studio注意到并标记为警告.
现在我有一个string,默认情况下可以为空,据我所知.
为什么我可以在string没有Visual Studio注意到硬编码的情况下将空条件运算符应用于硬编码?我在考虑这样的事情:
"This is a string"?.AnyStringMethod();
Run Code Online (Sandbox Code Playgroud)
Visual Studio不应该注意到它string根本不是null吗?
我有一个event返回一个boolean.为了确保只有在有人监听的情况下才触发事件,我使用空条件运算符(questionmark)来调用它.但是,这意味着我必须将null条件运算符添加到返回的布尔值中.这意味着我无法弄清楚如何在if语句中使用它.有谁知道如何处理这个?
switch (someInt)
{
case 1:
// Validate if the form is filled correctly.
// The event returns true if that is the case.
bool? isValid = ValidateStuff?.Invoke();
if (isValid)
// If passed validation go to next step in form
GoToNextStep?.Invoke();
break;
// There are more cases, but you get the point
(...)
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
IEnumerable<int> xx = null;
var tt = xx?.Where(x => x > 2).Select(x => x.ToString());
Run Code Online (Sandbox Code Playgroud)
它分配null给tt. 问题是:为什么它可以正常工作?
我想我必须?.在 Select as ?.Where(...)returns之前使用null。此外,如果我将第二行分成两行:
IEnumerable<int> xx = null;
var yy = xx?.Where(x => x > 2);
var zz = yy.Select(x => x.ToString());
Run Code Online (Sandbox Code Playgroud)
ArgumentNullException第三行会有yy == null。
有什么魔力?:)
如果这是因为短路,我从没想过它会像这样。
未来访问者的注意事项:此问题基于错误的repro代码.该?.运营商确实短路.您现在可以关闭此浏览器选项卡.
网上有很多来源声称空条件运算符(?.)短路(例如http://www.informit.com/articles/article.aspx?p=2421572,搜索"电路").我无法发现任何这样的事情:
static void Main()
{
var c = new C();
Console.WriteLine(c?.Inner?.Inner); //does not rely on short circuiting, works
Console.WriteLine(c?.Inner.Inner); //throws NullReferenceException
}
class C
{
public C Inner;
}
Run Code Online (Sandbox Code Playgroud)
这里,第一行是因为第二行?..第二个?.看到null作为其第一个操作数,因此也返回null.这不是短路.
显然,即使触发了null情况,链的其余部分也会执行.链条没有中止.对我来说,短路意味着链条中止.MSDN声称是这种情况,但代码示例并未证明短路:
//The last example demonstrates that the null-condition operators are short-circuiting
int? count = customers?[0]?.Orders?.Count();
// null if customers, the first customer, or Orders is null
Run Code Online (Sandbox Code Playgroud)
在C#6开发周期中,这种行为是否曾经发生过变化?这可以解释网络上的不良消息来源.如果不存在,为什么会有这么多关于短路的讨论呢?我可能在这里误解了一些东西.
我想知道这两个 if 语句之间的性能是否存在差异:
if(myObject != null && myObject.someBoolean)
{
// do something
}
if (myObject?.someBoolean ?? false)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
如果性能存在差异,支持哪种方法以及为什么?
编辑: 这不是我的应用程序的瓶颈,我并不是试图过度优化,我只是好奇。
c# ×8
c#-6.0 ×2
.net ×1
boolean ×1
delegates ×1
events ×1
null-check ×1
performance ×1
string ×1
winforms ×1