简体   繁体   English

接线员'?'不能应用于'方法组'类型的操作数

[英]Operator '?' cannot be applied to operand of type 'method group'

This is a question about C#'s newly introduced null-checking operator. 这是关于C#新引入的空检查运算符的问题。

Assuming I have an interface like: 假设我有一个界面,如:

interface ILogger
{
    void Log(string message);
}

and a function that expects a logging action: 和一个期望记录操作的函数:

void DoWork(Action<string> logAction)
{
    // Do work and use @logAction
}

Why do I get the following compiler error if I try to write: 如果我尝试编写,为什么会出现以下编译器错误:

void Main(string[] args)
{
    ILogger logger = GetLogger(); // Assume GetLogger() may return null

    //
    // Compiler error: 
    // Operator '?' cannot be applied to operand of type 'method group'
    //
    DoWork(logger?.Log);   
}

There's nothing special going on with ?. 没有什么特别的事?. here, it works just like it does with ?: : logger?.Log would give the same result as logger == null ? null : logger.Log 在这里,它的工作原理就像它一样?: logger?.Log会得到与logger == null ? null : logger.Log相同的结果logger == null ? null : logger.Log logger == null ? null : logger.Log , except for logger only being evaluated once. logger == null ? null : logger.Log ,除了仅logger一次的logger

The problem is that logger == null ? null : logger.Log 问题是logger == null ? null : logger.Log logger == null ? null : logger.Log is just as invalid in earlier versions of C#. logger == null ? null : logger.Log在早期版本的C#中同样无效。 ?: requires one operand to be convertible to the type of the other, but neither null nor logger.Log have a type. ?:要求一个操作数可以转换为另一个操作数的类型,但是nulllogger.Log都没有类型。 You'd have to write that as eg logger == null ? null : (Action<string>) logger.Log 你必须把它写成例如logger == null ? null : (Action<string>) logger.Log logger == null ? null : (Action<string>) logger.Log . logger == null ? null : (Action<string>) logger.Log

Unfortunately, the introduction of that cast means there's no simple pretty C# 6 shortened version you can use, as the same applies to ?. 不幸的是,这个演员的介绍意味着你不能使用简单漂亮的C#6缩短版本,因为同样适用于?. : logger?.Log is invalid because logger.Log does not have a type, so logger?.Log doesn't have a type either, but if it's an expression without a type, and it's not a method group, then there's nothing C# would let you do with it. logger?.Log是无效的,因为logger.Log没有类型,所以logger?.Log也没有类型,但是如果它是没有类型的表达式,并且它不是方法组,那么就没有C#会让你做到的。

If you are able to change your interface to 如果您能够将界面更改为

interface ILogger
{
    //void Log(string message);
    Action<string> Log {get; }
}

Then you could use the logger?.Log notation. 然后你可以使用logger?.Log表示法。

The ILogger implementation would then look something like 那么ILogger的实现就像是

class Logger : ILogger
{
    Action<string> Log => str => { /* Do stuff with str */ };
}

Adding to @hvd statement 添加到@hvd语句

We can also use Null Conditional Operator ( ?. ) with Null-Coalescing Operator ( ?? ) If you write following code 我们也可以使用Null条件运算符(?。)Null-Coalescing运算符(??)如果你编写下面的代码

string userName = null;
int len = userName.Length;

then 然后

userName.Length

will throw the exception: "An unhandled exception of type 'System.NullReferenceException' occurred in ConsoleApplication... Additional information: Object reference not set to an instance of an object." 将抛出异常:“ConsoleApplication中发生了'System.NullReferenceException'类型的未处理异常...附加信息:对象引用未设置为对象的实例。”

if you use the following code 如果您使用以下代码

string userName = null;
int? len = userName.Length;

still you will get the same exception 你仍会得到同样的例外

But

int? len = userName?.Length;

It will return null and will not throw the exception 它将返回null并且不会抛出异常

But we are still having an issue. 但我们仍有问题。 The issue is I am using int? 问题是我使用int? (Nullable int) which is not good because people will prefer that if string is null then it should return 0. (Nullable int)这是不好的,因为人们会更喜欢如果string为null,那么它应该返回0。

So we can do this by combination of null Conditional Operator(?.) and null-coalescing Operator(??) 所以我们可以通过组合null条件运算符(?。)和null-coalescing Operator(??)来实现这一点。

int len = userName?.Length ?? 0;

Added 添加

we have another usage of null conditional operator too. 我们还有另一种使用null条件运算符的方法。

like when you are working with event handling in that case we can use 就像你在这种情况下处理事件处理时一样,我们可以使用

myCustomEventHandler?.Invoke(this, EventArgs.Empty); myCustomEventHandler?.Invoke(this,EventArgs.Empty);

where "myCustomEventHandler" is public event before C#6.0 we have to create local copy of "myCustomEventHandler" otherwise it may throw exception in case of muti-threaded application. 其中“myCustomEventHandler”是C#6.0之前的公共事件,我们必须创建“myCustomEventHandler”的本地副本,否则它可能会在多线程应用程序中抛出异常。 whereas in C# 6 we can directly call the "myCustomEventHandler" without creating local copy and it is thread safe. 而在C#6中,我们可以直接调用“myCustomEventHandler”而不创建本地副本,它是线程安全的。

eg in C# 5 例如在C#5中

var handler= this.myCustomEventHandler;
if (handler!= null)
    handler(…)

in C# 6 在C#6中

myCustomEventHandler?.Invoke(e)

暂无
暂无

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

相关问题 运算符&#39;==&#39;不能应用于&#39;方法组&#39;类型的操作数 - Operator '==' cannot be applied to operand of type 'method group' 运算符“!” 不能应用于“方法组”类型的操作数 - Operator '!' cannot be applied to operand of type 'method group' “。” 运算符不能应用于类型为“方法组”(CS0023)(CurrencyConverter.Droid)的操作数 - The `.' operator cannot be applied to operand of type `method group' (CS0023) (CurrencyConverter.Droid) 运算符 &lt; 不能应用于“方法组”类型的操作数 - Operator < cannot be applied to operands of type "method group" 错误1运算符&#39;&gt; =&#39;不能应用于类型为&#39;方法组&#39;和&#39;方法组&#39;的操作数 - Error 1 Operator '>=' cannot be applied to operands of type 'method group' and 'method group' 运算符“ ==”不能应用于“方法组”和“方法组”类型的操作数 - Operator `==' cannot be applied to operands of type `method group' and `method group' 接线员&#39;!&#39; 不能应用于x类型的操作数 - Operator '!' cannot be applied to operand of type x 运算符“ ”不能应用于类型的操作数<int>和空 - Operator ' ' cannot be applied to operand of type <int> and null 操作员! 不能应用于Task类型的操作数 <bool> - Operator ! cannot be applied to operand of type Task<bool> 运算符&#39;&amp;&amp;&#39;不能应用于&#39;bool&#39;和&#39;int&#39;类型的操作数 - Operator '&&' cannot be applied to operand of type 'bool' and 'int'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM