РЕДАКТИРОВАТЬ: старый ответ оставлен для исторического значения ниже линии ...
CLR должен был бы отработать случаи, когда скрытые классы можно было бы считать равными, принимая во внимание все, что можно было бы сделать с захваченными переменными.
В этом конкретном случае захваченная переменная (x
) не изменяется ни внутри делегата, ни в контексте захвата - но я бы предпочел, чтобы язык не требовал такого рода сложности анализа. Чем сложнее язык, тем сложнее его понять. Нужно было бы различить этот случай и тот, который приведен ниже, где значение захваченной переменной изменяется при каждом вызове - там есть большая разница, какой делегат вы вызываете; они ни в коем случае не равны.
Я думаю, что вполне разумно, что эта и без того сложная ситуация (закрытие часто понимается неправильно) не пытается быть слишком "умной" и вырабатывает потенциальное равенство.
IMO, вы должны определенно выбрать другой маршрут. Это концептуально независимые экземпляры Action
. Фальсификация этого путем принуждения делегатов к целям - ужасный взлом IMO.
Проблема в том, что вы захватываете значение x
в сгенерированном классе. Две переменные x
являются независимыми, поэтому они являются неравными делегатами. Вот пример, демонстрирующий независимость:
using System;
class Test
{
static void Main(string[] args)
{
Action first = CreateDelegate(1);
Action second = CreateDelegate(1);
first();
first();
first();
first();
second();
second();
}
private static Action CreateDelegate(int x)
{
return delegate
{
Console.WriteLine(x);
x++;
};
}
}
Выход:
1
2
3
4
1
2
РЕДАКТИРОВАТЬ: Чтобы посмотреть на это по-другому, ваша оригинальная программа была эквивалентна:
using System;
class Test
{
static void Main(string[] args)
{
bool same = CreateDelegate(1) == CreateDelegate(1);
}
private static Action CreateDelegate(int x)
{
return new NestedClass(x).ActionMethod;
}
private class Nested
{
private int x;
internal Nested(int x)
{
this.x = x;
}
internal ActionMethod()
{
int z = x;
}
}
}
Как вы можете сказать, будут созданы два отдельных экземпляра Nested
, и они будут целями для двух делегатов. Они неравны, поэтому и делегаты неравны.