我一直在研究Visual Studio 14 CTP和C#6.0以及使用零传播运算符.
但是,我找不到为什么以下代码无法编译.这些功能尚未记录,所以我不确定这是一个错误还是扩展方法,?.操作员不支持这些方法并且错误消息具有误导性.
class C
{
public object Get()
{
return null;
}
}
class CC
{
}
static class CCExtensions
{
public static object Get(this CC c)
{
return null;
}
}
class Program
{
static void Main(string[] args)
{
C c = null;
var cr = c?.Get(); //this compiles (Get is instance method)
CC cc = null;
var ccr = cc?.Get(); //this doesn't compile
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
错误信息是:
'ConsoleApplication1.CC'不包含'Get'的定义,也没有扩展方法'Get'接受类型'ConsoleApplication1.CC'的第一个参数(你是否缺少using指令或汇编引用?)
我一直在研究C#6中的零传播运算符,并尝试使用dynamic类型的变量,但没有成功.考虑下面的代码,它会编译,但是AccessViolationException当将null传播应用于动态对象时,CLR会在运行时抛出.
class SomeType
{
public object SomeProperty { get; set; }
static void Main()
{
var obj = new SomeType() { SomeProperty = "ABCD" };
var p1 = ((dynamic)obj).SomeProperty; //OK, p1 is set to "ABCD"
var p2 = ((dynamic)obj)?.SomeProperty; //AccessViolationException
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
起初我认为这可能是一个错误,但后来我想到了structs.通常,您不能将?.运算符应用于值类型变量(因为它不能为null).但是您可以将其转换为dynamic然后应用运算符.所以我改成SomeType了struct并得到了同样的例外.
问题是,根据设计,动态变量的零传播总是会抛出异常,因为底层对象可能是值类型?
AccessViolationException无论如何,这是非常丑陋的,当你运行代码时,你得到相同的一个吗?
Maybe switchIfEmpty如果源Maybe为空,我使用方法提供替代结果.但是,我希望仅在源为空时执行备用源,而在源不为空时不执行备用源.
在下面的例子中,我想避免执行costlyFallback如果源返回非空Maybe.当前实现总是调用它,因为它需要传递给switchIfEmpty方法.Maybe.fromCallable看起来很有希望,但它只适用于不包括返回a的callables Maybe.empty.任何提示都表示赞赏.如果switchIfEmpty愿意接受一些懒惰的评估Maybe提供者会很好.
public class StartRxMaybe {
public static void main(String... args) {
System.out.println(new StartRxMaybe().start().blockingGet());
}
private Maybe<Integer> start() {
return func()
.switchIfEmpty(costlyFallback());
}
private Maybe<Integer> func() {
System.out.println("Non-empty maybe returned");
return Maybe.just(1);
}
private Maybe<Integer> costlyFallback() {
System.out.println("Fallback executed anyway");
return LocalDate.now().getMonth() == Month.JULY
? Maybe.just(2)
: Maybe.empty();
}
}
Run Code Online (Sandbox Code Playgroud)