2012-11-26 17 views
4

Я пытаюсь очистить свой код для инициализации статических переменных readonly.Как инициализировать статическую переменную readonly с помощью анонимного метода?

Оригинал:

public static readonly List<int> MyList; 

//Initialize MyList in the static constructor 
static MyObject() { ... } 


Я решил очистить его, потому что CodeAnalysis сказал, что не следует использовать статический конструктор (CA1810).

Cleanup:

public static readonly List<int> MyList = GetMyList(); 

//Returns the list 
private static List<int> GetMyList() { ... } 


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

public static readonly List<int> MyList = 
    () => 
     { 
      ... 

      return list; 
     }; 

Я попытался взять код в методе GetMyList() и поместить его в анонимный делегат возвращает список, чтобы назначить, но он говорит, я Я пытаюсь преобразовать delegate в List<int>?

ответ

4

Это выглядит немного странно, но попробуйте это:

public static readonly List<int> MyList = new Func<List<int>>(
() => 
{ 
    // Create your list here 
    return new List<int>(); 
})(); 

Уловка создания нового Func<List<int>> и ссылающегося на него.

+0

Это довольно странно, может быть, лучше сохранить его в стандартном методе? – michael

+0

@michael Возможно - зависит от того, что вы считаете более читаемым и поддерживаемым. Постоянны ли эти значения? Не могли бы вы использовать 'public static readonly Список MyList = новый Список {1, 2, 3};'? –

+0

Нет, есть нечто большее, чем в противном случае, в противном случае это было бы очень легко. – michael

1

Это говорит правильно. () => ... возвращает делегата. Но вам нужен список. По этой причине вы должны позвонить этому делегату и получить результат.

4

Причина заключается в том, что когда вы пишете

() => 
    { 
     ... 

     return list; 
    }; 

Вы фактически объявляя делегат - функция, которая возвращает List<int>, но вы на самом деле не вызывающую эту функцию, и, следовательно, это оценивает в Func<List<int>> и не до List<int>.

Я не совсем понимаю, почему вы пытаетесь удалить свой статический конструктор. Статические конструкторы используют их, а в некоторых случаях даже делают код более понятным и понятным.

+0

+1. Да, чтобы получить результат, нужно вызвать функцию ... также я предпочитаю для нее отдельную функцию. «iffe» выглядит более естественно в JavaScript :) –

2

он говорит, что я пытаюсь преобразовать делегата в List<int>

Это потому, что вы. Помните, что определение лямбда - это не то же самое, что вызывать лямбду. Вы должны были бы делать что-то больше, как это:

Func<List<int>> createList =() => { ... return list; }; 
MyList = createList(); 
2

Вы должны немедленно вызвать его, чтобы он стал список:

public static readonly List<int> MyList = new Func<List<int>>(() => { 
    return new List<int>(); 
})(); //<-- the parentheses that invoke 

с синтаксисом в C# для этого настолько сомнительны, что это, вероятно, лучше пойти с отдельным вызовом или метода.

0

Как многие заявили, простой () => { ... } возвращает делегат или выражение.Я думаю, что создание отдельного метода private static для инициализации списка делает немного более читаемый код, чем () => { ... }() или () => { ... }.Invoke()

+0

BTW, альтернативные синтаксисы, которые вы предлагаете (но отклоните как менее читаемые), не компилируются. (Я рекомендую удалить этот ответ.) – ToolmakerSteve

1

Вы забыли скобки. Используйте это:

public static readonly List<int> MyList = (() => 
{ 
    ... 
    return list; 
}); 
+0

ПРЕДОСТЕРЕЖЕНИЕ: ** Не компилируется. ** Я подтвердил это, после тестирования другого варианта, в другой ситуации, где я действительно * * нуждался в делегате, а не в оценке. Теперь я не могу изменить свое положение. – ToolmakerSteve

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