2016-11-23 2 views
0

Я просто привык к использованию лямбда и всему этому хорошему. Однако я не знаю, какой аргумент мне нужно предоставить в этом случае.T [] параметр в строке []. Foreach()

Я пытаюсь изменить строку I, чтобы заменить все экземпляры записи в словаре с ее значением, ничего необычного, я мог бы сделать это с помощью простого цикла foreach, но я пытаюсь использовать его в качестве учебного упражнения ,

Мой код до сих пор выглядит следующим образом:

 string maskString = Masks[alias]; 
     Regex regex = new Regex(@"({[\w+|\d]+})"); 
     MatchCollection matches = regex.Matches(maskString); 
     string[] constants = matches.Cast<Match>().Select(m => m.Value).ToArray(); 
     string maskedString = ""; 
     if (constants.All(constant => Constants.ContainsKey(constant))) 
     { 
      constants.ForEach(constant => maskedString = maskedString.Replace(constant, Constants[constant])); 
     } 

Однако, я получаю эту ошибку: There is no argument given that corresponds to the required formal parameter 'action' of 'Array.ForEach<T>(T[], Action<T>)'. Мне кажется, что я предоставляю действие в форме выражения lambda, но я понятия не имею, зачем ему нужен другой массив или какой массив я должен ему дать.

Я попытался предоставить его null, string[] и new [] {typeof(string)}, но это просто вызывает больше ошибок.

Возможно ли, чтобы эта операция проводилась с использованием этой структуры или было бы более практичным использовать традиционный цикл foreach?

+3

Array.ForEach не метод расширения (это просто статический метод Array), поэтому использовать его как это: 'Array.ForEach (константы, константа => maskedString = maskedString.Replace (константа, константы [константа])); в любом случае, я бы предпочел стандартный цикл foreach, когда задействованы побочные эффекты. – digEmAll

+0

Держите его простым и удобным. Операторы LINQ могут быть полезны, но их также трудно интерпретировать. –

+0

@ digEmAll Я заметил, что как раз перед тем, как вы прокомментировали, просмотрев документы (https://msdn.microsoft.com/en-us/library/zecdkyw2(v=vs.110).aspx), я действительно не видел этот комментарий, пока я не отправил свой ответ, но спасибо! Из интереса, почему это метод расширения для большинства 'IEnumerable ' s, но не '[]' s? –

ответ

1

В любое время вы бы лучше использовать Агрегатную функцию:

maskedString = constants.Aggregate(maskedString, (current, constant) => current.Replace(constant , Constants[constant])); 
+0

Мне это нравится ... Мне это очень нравится. Благодаря! –

+0

@JamesHughes спасибо, не могли бы вы быть добрыми и отметить ответ как решение :) –

1

Похоже, что это неправильное использование метода .ForEach(), это метод static класса Array, а не метод расширения. Есть два способа выполнить это правильно:

Во-первых, использует Array.ForEach (статический метод) и обеспечивает массив в качестве первого параметра:

Array.ForEach(constants,constant => maskedString = maskedString.Replace(constant, Constants[constant])); 

Во-вторых, отбрасывает массив к первому List<T>:

constants.ToList().ForEach(constant => maskedString = maskedString.Replace(constant, Constants[constant])); 

Второй метод не изменяет исходный массив и, следовательно, если это требуется вам придется сделать myArray = myArray.ToList().ForEach().ToArray(). Спасибо Крису за это.

+0

Обратите внимание, что ваш второй будет * не * работать отлично. Он создаст новый объект List и затем будет работать с этим объектом. Исходный массив констант не будет изменен. Вместо этого вам нужно будет выполнить 'constants = (ваше выражение).ToArray(); ' – Chris

+0

@ Крис, я на самом деле не изменить исходный массив, я просто использовать его, чтобы изменить отдельную строку, но это важное уточнение для тех, кто еще читает эту –

+0

Моей точки является то, что без присвоения вашего второй делает абсолютно ничего. Это не просто «если это было необходимо», потому что если его не требуется, вы также можете не помещать свою строку кода. – Chris