【发布时间】:2018-03-10 05:51:12
【问题描述】:
我在尝试从匿名函数转换为方法组时偶然发现了一个奇怪的问题。下面的示例完美地说明了这个问题 - 有 2 种方法 - Run() 和 Crash(),除了使用匿名函数与方法组之外,它们所做的一切都是相同的。
基本上问题是我想创建一个 Func 来调用对象上的方法,该方法在应用程序启动时未初始化,而是稍后出现,在此 func 运行之前。使用匿名函数效果很好,但转换为方法组会导致异常。
坚持使用匿名函数而不是方法组并不是什么大不了的事,但是出现了一个 roslynator 警告 RCS1207,我想先了解此问题的原因,然后再使用内联注释将其禁用。
namespace AnonymousFunctionVsmethodGroup
{
class Program
{
static void Main(string[] args)
{
var app = new App();
app.Run();
app.Crash();
}
}
public class App
{
private Func<string> m_Func;
public void Run()
{
Entity cat = null;
// Anonymous function. At this point cat is null
m_Func = () => cat.GetName();
// Initializing new cat
cat = new Entity("Cat");
// Func is executed on a valid cat
Console.WriteLine(m_Func());
Console.Read();
}
public void Crash()
{
Entity cat = null;
// Method group. At this point cat is null. Code never gets through here and an exception is thrown instead.
// "Delegate to an instance method cannot have null this"
m_Func = cat.GetName;
// Initializing new cat
cat = new Entity("Cat");
// Func is executed on a valid cat?
Console.WriteLine(m_Func());
Console.Read();
}
}
// Sample entity
public class Entity
{
private string name;
public Entity(string name)
{
this.name = name;
}
public string GetName()
{
return name;
}
}
}
【问题讨论】:
-
您实际上是在尝试在
Crash中使用特定的(或缺少的)cat实例。你怎么不期望那会出错? lambda 之所以有效,是因为 lambda 在被调用之前不是可执行代码。由于您在实际调用 lambda 之前实例化了实例,因此没有错误。如果你交换这些行——初始化和调用——那么你应该看到同样的错误(NRE)。您可能会收到关于潜在 NRE 的 lambda 用法的 IDE 警告。 -
感谢您的解释,但我仍然感到困惑。在崩溃示例中 - cat.GetName 被分配给一个 func,我假设在调用该 func 之前不会执行它。这不正确吗?我知道在初始化 cat 之前简单地调用 var myVar = cat.GetName() 会导致 NRE。
-
我想我的问题很简单——以下 2 个语句是否不相同: Func
myFunc = () => myObject.DoStuff(); Func myFunc = myObject.DoStuff; -
另外,IIRC,lambda 正在围绕
cat创建一个闭包。这允许 lambda 在cat实例化后访问更新的引用。 -
@Ross 他们不一样
标签: c# .net anonymous-function method-group