【发布时间】:2021-07-12 23:35:57
【问题描述】:
我在尝试从返回 IEnumerable 的函数创建委托时遇到了一些奇怪的行为。在前三个实例中,我可以传入一个空“this”并接收有效结果,但是在结构和产量返回的组合中,我遇到了运行时 NullReferenceException。请参阅下面的代码以复制问题。
class Program
{
public delegate IEnumerable<int> test();
static void Main(string[] args)
{
var method2 = typeof(TestClass).GetMethod("testReturn");
var test2 = (test)Delegate.CreateDelegate(typeof(test), null, method2);
var results2 = test2.Invoke();
Console.WriteLine("This works!");
var method = typeof(TestClass).GetMethod("testYield");
var test = (test)Delegate.CreateDelegate(typeof(test), null, method);
var results = test.Invoke();
Console.WriteLine("This works!");
var method3 = typeof(TestStruct).GetMethod("testReturn");
var test3 = (test)Delegate.CreateDelegate(typeof(test), null, method3);
var results3 = test3.Invoke();
Console.WriteLine("This works!");
var method4 = typeof(TestStruct).GetMethod("testYield");
var test4 = (test)Delegate.CreateDelegate(typeof(test), null, method4);
var results4 = test4.Invoke();
Console.WriteLine("This doesn't work...");
}
public class TestClass
{
public IEnumerable<int> testYield()
{
for (int i = 0; i < 10; i++)
yield return i;
}
public IEnumerable<int> testReturn()
{
return new List<int>();
}
}
public struct TestStruct
{
public IEnumerable<int> testYield()
{
for (int i = 0; i < 10; i++)
yield return i;
}
public IEnumerable<int> testReturn()
{
return new List<int>();
}
}
}
当我传入 default(TestStruct) 而不是 null 时,它确实工作,但是我将无法在运行时以这种方式引用正确的类型。
编辑:我能够通过使用 Activator.CreateInstance 而不是 null 来动态创建一个虚拟对象来解决这个问题。不过,我仍然对造成此问题的收益率回报有何不同感兴趣。
【问题讨论】:
-
结构实例方法有一个隐藏的 byref
this参数。如果你传递 null (结构不能是)你会得到异常。default()之所以有效,是因为没有 no 结构,而是有一个 default 结构。您需要一个接受结构类型的单个ref参数的委托类型 -
@pinkfloydx33 我以为是这样的,谢谢。尽管从结构实例方法创建的第一个委托确实适用于空引用。出于某种原因,添加收益回报会引入问题。
-
嗯... Yield return 在后台创建了一个状态机,这意味着它正在分配类来完成工作。可能是机器中的某些东西,然后从显示类或其他任何东西中取消引用该字段。