2015-09-19 1 views
1

При осуществлении IDataErrorInfo следующий код компилируется и работает без проблем:Почему func <> в поле инициализатор статичен?

public string Error 
     { 
      get { return null; } 
     } 

     public string this[string columnName] 
     { 
      get 
      { 
       switch (columnName) 
       { 
        case "MemberId":   return validate(MemberId,   0, RegexLibrary.NonEmptyRegex); 
        case "PolicyType":   return validate(PolicyType,   1, RegexLibrary.NonEmptyRegex); 
        case "EffectiveDateFrom": return validate(EffectiveDateFrom, 2, RegexLibrary.DateRegex); 
        case "EffectiveDateTo":  return validate(EffectiveDateTo, 3, RegexLibrary.DateRegex); 
        case "Phone":    return validate(Phone,    4, RegexLibrary.PhoneRegex); 
        case "CompanyName":   return validate(CompanyName,  5, RegexLibrary.NonEmptyRegex); 
       } 
       // string.Empty is no error. 
       return string.Empty; 
      } 
     } 

public string validate(string column, int position, string regex) 
     { 
      string invalid = string.Format("{0} is invalid.", column); 
      if (column == null) 
      { 
       SetErrorStatus(1, position); 
       return invalid; 
      } 

      Match match = Regex.Match(column, regex); 
      if (!match.Success) 
      { 
       SetErrorStatus(1, position); 
       return invalid; 
      } 

      SetErrorStatus(0, position); 
      return string.Empty; 
     } 

Однако, если Validate (...) определяется как функция, как так:

Func<string, int, string, string> validate = (column, position, regex) => 
     { 
      string invalid = string.Format("{0} is invalid.", column); 
      if (column == null) 
      { 
       SetErrorStatus(1, position); 
       return invalid; 
      } 

      Match match = Regex.Match(column, regex); 
      if (!match.Success) 
      { 
       SetErrorStatus(1, position); 
       return invalid; 
      } 

      SetErrorStatus(0, position); 
      return string.Empty; 

     }; 

Компилятор определяет validate (...) func как static. Зачем?

ТИА

+1

'validate' lambda не использует' this', поэтому нет причины генерировать метод экземпляра, чем анонимный метод. – PetSerAl

+0

@PetSerAl Может ли func <> проверять, чтобы быть нестационарным? –

+1

Какой смысл сделать метод поддержки делегата нестационарным? Вы всегда можете написать метод самостоятельно и создать делегат из него. Кстати, поскольку вы не можете ссылаться на 'this' в инициализаторе поля, вы не можете создать делегат из нестатического метода текущего экземпляра в инициализаторе поля, это должно быть сделано в конструкторе. – PetSerAl

ответ

1

В этом случае validate не метод, но поле. Поле является членом экземпляра. Объект, назначенный этому полю, является делегатом, который ссылается на анонимный метод. Нет причин для того, чтобы этот метод был членом экземпляра, потому что он не ссылается на текущий экземпляр. Итак, у вас есть поле экземпляра, ссылающееся на статический метод.

+0

Может ли func <> validate быть нестационарным? Благодарю. –

+0

@jmcilhinney Хороший ответ, могу ли я знать, является ли это просто концептуальным знанием C# для вас или вы тоже научились этому? Как и Алан, я даже не заметил об этом до сегодняшнего дня. Ты заставил меня начать расспрашивать о себе. – cscmh99

+1

* Нет причин для того, чтобы этот метод был членом экземпляра, потому что он не ссылается на текущий экземпляр. * Говорит, кто? Это деталь реализации компилятора, которая изменила BTW. –

1

Тот факт, что компилятор генерирует static метод на классе вызывающего вместо экземпляра один деталь реализации компилятора, которая может быть изменена, и на самом деле изменился с выпуском Рослин. Вы можете увидеть Delegate caching behavior changes in Roslyn и увидеть, что теперь компилятор генерирует класс отображения даже для не захвата делегатов.

Я не вижу, как это связано с объявлением чего-либо как static внутри вашего класса.

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