目前在C#中的写法是这样的:
var refreshToken = await Get(id); if (refreshToken != null) { refreshToken.IsActive = false; }
想使用C# 6.0的Null条件运算符改写,请问该如何写?
想达到类似这样的效果:
目前有2个折衷的解决方法:
1)不优雅的解决方法
((await Get(id)) ?? new RefreshToken()).IsActive = false;
2)丑陋的解决方法
给RefreshToken类增加一个SetIsActive方法:
public bool IsActive { get; set; } public void SetIsActive(bool value) { IsActive = value; }
然后使用Null条件运算符时调用这个方法:
(await Get(id))?.SetIsActive(false);
按照它的规则,应该是:refreshToken?.IsActive = false; 还没安装4.6,没法测试。
这样写不行,见下图:
@dudu: 那看来是设定问题了~~
refreshToken?.IsActive = false;//no var isActive = refreshToken?.IsActive;//yes
?判断是否为null,应该只能get,而不能set。
我好奇的是为什么set就不可以。
Null条件运算符是支持方法调用的。
如果给RefreshToken加一个SetIsActive()方法就可以:
(await Get(id))?.SetIsActive(false);
而IsActive属性在编译时,实际也是被转换为get_IsActive与set_IsActive方法。如果这个set_IsActive方法可以被调用,就可以进行set。或者编译器将?.IsActive=false;翻译为set_IsActive方法调用。
@田园里的蟋蟀: 第1个链接错了地址
@dudu: 已修改。
私以为:
refreshToken?.IsActive = false;其IsActive属性是一直可以get、set的。
而目前编译器只实现了Get操作,还没支持Set,所以推断不出art不为空就赋值给prop1、为空就不
赋值的行为。
加一个SetIsActive()这个可以,是因为?.已经明确了refreshToken不为空才调方法,所以方法内赋值是理所当然的。
或许7.0就有了。
这个设定应该是有问题的,因为refreshToken?.IsActive返回的实际上是一个bool拷贝值,估计代码检测是这样理解的:
而这个返回的bool值是不能被赋值的。实际上,从“Null条件运算符”的字面意义来看,它是一个运算符,结果是一个右值且是值类型,这个结果当然不能赋值了。
如果IsActive换成引用类型的值,这种写法是没问题的:
我实际想进行的操作是 refreshToken?(.IsActive = false) ,是希望编译器将 .IsActive = false 翻译为对set_IsActive(false)方法的调用。
@dudu: 比如(a==b)=false,这样肯定语法错误,这个运算符就是提供一个返回值,能执行什么操作时返回值决定的
@以吾之名: 那为什么调用方法就可以呢?
refreshToken?.SetIsActive(false);
@dudu:
https://roslyn.codeplex.com/discussions/540281
请参考上面这篇文章,里面提到:
Semantics
The semantics are like applying the ternary operator to a null equality check, a null literal and a non-question-marked application of the operator, except that the expression is evaluated only once:
Where e0
is the same as e
, except if e
is of a nullable value type, in which case e0
is e.Value
所以实际上,代码等同如下:
refreshToken?.IsActive=false => (int?)((refreshToken==null)?null:refreshToken.IsActive)=false
refreshToken?.SetIsActive(false) => ((refreshToken==null)?null:refreshToken.SetIsActive(false))
@dudu: 这个操作符应该类似“.”成员操作符,但是和成员操作符是有区别的,正常的成员操作符能直接处理属性赋值,但是这个操作符不行
@以吾之名: 是的,就是Roslyn解析的问题,如果Roslyn能改进一下,应该可以解决这个问题。