2016-10-07 8 views
0

У меня есть ситуация, когда код ведет себя по-другому, если скомпилирован в двух разных блоках разработки. Я не могу понять, почему. Я не уверен, какие ключевые слова лучше всего описывают эту проблему.Захват выражения, когда он должен ссылаться на экземпляр класса

Когда Кролик вызывается на одном источнике коробки имеет значение

{() => Program.Names} 

На другом источнике коробки имеет значение

{() => value(NPC.Program+<>c__DisplayClass1_0).Names} 

Отверстие всегда имеет значение независимо от того, на каком компьютере он собран на.

{() => value(NPC.Program+<>c__DisplayClass1_0).closure} 

Я пытаюсь выяснить, почему одна машина имеет выражение для класса, а другая машина имеет значение для закрытия при вызывающему Кролика. Я также хотел бы знать, есть ли способ контролировать это. Благодаря!

class Program 
{ 
    public static ObservableCollection<string> Names = new ObservableCollection<string>(); 

    static void Main(string[] args) 
    { 
     string closure = "closure"; 

     if(closure.Length > 0) 
     { 
      GoingDown(p => { 
       closure.ToString(); 
       Names = new ObservableCollection<string>(); 

       Rabbit(() => Names); 
       Hole(() => closure); 
      }, closure); 
     } 
    } 

    public static void Rabbit<SourceType>(Expression<Func<ObservableCollection<SourceType>>> source) 
    { 
     "Testing".ToString(); 
    } 

    public static void Hole(Expression<Func<object>> source) 
    { 
     "Testing".ToString(); 
    } 

    public static void GoingDown(Action<object> a, object target) 
    { 
     Action b =() => 
     { 
      a(target); 
     }; 

     b(); 
    } 
} 
+2

Какие версии C# и какой .net-каркас на обеих системах? – RBarryYoung

ответ

4

Во-первых: как указывает комментарий, было бы полезно знать, какие версии .NET/C#/etc производят какое поведение.

Во-вторых: какое поведение, если оно, правильно? Спецификация не говорит. Он предоставляет широкую широту компилятора для реализации lambdas в качестве делегатов и деревьев выражений по своему усмотрению.

В-третьих: что лучше? Просто нет необходимости копировать статические имена полей в класс закрытия. Я ожидаю, что будет создана версия, не относящаяся к закрытию; Я подозреваю, что версия, которая генерирует замыкание, имеет ошибку. Возможно, ошибка была исправлена ​​в любой версии, не отображающей семантику закрытия.

В-четвертых: вы можете контролировать это поведение? Очевидно, да; у вас есть одна машина, которая имеет поведение, а другая - нет, поэтому вы можете просто отказаться от машины, которая имеет плохое поведение на дне океана, и использовать машину, которая имеет желаемое поведение.

В качестве альтернативы: нет необходимости использовать реализацию компилятора лямбда-семантики. Lambdas - синтаксический сахар; не стесняйтесь генерировать деревья выражений «вручную», если вам не нравится дерево выражений, которое дает вам компилятор.

+0

Вместо того, чтобы пытаться заставить lambdas генерировать версию, которая вам нравится, или катиться самостоятельно, я бы подумал, что было бы лучше просто изменить ваши анализаторы выражений, чтобы нормально функционировать с любым семантически допустимым выражением, а не жестко кодировать его фиксированная реализация. Вы не должны * заботиться о том, какие частные детали реализации, а не пытаться упорядочить конкретные детали частной реализации, которые вы хотите. – Servy

 Смежные вопросы

  • Нет связанных вопросов^_^