Как вернуть тип из анонимного метода/делегата

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

            StringBuilder sb = new StringBuilder("aaa");
            sb.Replace("aaa", delegate()
            {
                return "bbb";
            });

Я также пытаюсь создать метод расширения, чтобы я мог писать код, например:

StringBuilder sb = new StringBuilder("aaa");
sb.Replace("aaa", () =>                
{
  return "bbb";
});

Какой будет подпись метода расширения?

РЕДАКТИРОВАТЬ:

У нас есть большой внутренний класс, который генерирует утомительные xml-файлы. Мы хотим сделать метод более читабельным, больше всего на свете. Итак, мы хотим перейти от:

StringBuilder sb = new StringBuilder(_repository.GetGenericXml1Template());
sb.Replace("$Placeholder", GetXml1Helper());

private void string GetXml1Helper()
{
   StringBuilder sb = new StringBuilder(_repository.GetGenericXml2Template());
   sb.replace("$Var1", DB.Var1);
   ....
   return  sb.ToString();
}

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

To:

StringBuilder sb = new StringBuilder(_repository.GetGenericXml1Template());
sb.Replace("$Placeholder", () =>
{
   StringBuilder sb = new StringBuilder(_repository.GetGenericXml2Template());
   sb.replace("$Var1", DB.Var1);
   ....
   return  sb.ToString();
}
);

person Community    schedule 13.10.2009    source источник
comment
Подпись будет Func‹String›, но зачем вам делать что-то подобное? Я уверен, что есть лучшее решение для того, чего вы пытаетесь достичь.   -  person Groo    schedule 13.10.2009
comment
@Вололо, ты проверил мой ответ...   -  person RameshVel    schedule 13.10.2009


Ответы (7)


Обратите внимание, что это приведет к ошибке времени компиляции: невозможно преобразовать анонимный метод в тип «строка», поскольку он не является типом делегата.

Ваш делегат в порядке — ошибка просто говорит, что его нельзя использовать здесь, потому что Replace ожидает string в качестве второго аргумента.

Какой будет подпись метода расширения?

Ну, что-то вроде этого:

static void Replace(this StringBuilder sb, Func<string> f);

- но зачем тебе это? Какой вариант использования он выполняет?

person Konrad Rudolph    schedule 13.10.2009
comment
У нас большой класс создает xml на лету. Наши xml-файлы глубоко вложены друг в друга, поэтому вместо создания десятков маленьких вспомогательных методов я решил попробовать анонимный метод, чтобы он читался намного лучше. Делегаты будут представлять другой вложенный уровень xml. Методы замены заменяют $Placeholders в файле шаблона xml значениями из базы данных. - person ; 13.10.2009

Вместо StringBuilder.Replace вы можете заглянуть в Regex.Replace. Таким образом, вы можете сделать что-то вроде:

Regex.Replace("Input string", "aaa", match => "bbb");

Очень похоже на то, что вы хотите сделать, просто из коробки.

person Geoff    schedule 13.10.2009

Вы должны использовать метод расширения для достижения ожидаемого..

поскольку StringBuilder.replace по умолчанию не принимает Func‹>, вам необходимо создать замену метода расширения, которая соответствует вашим требованиям.

вот пример кода.

public static class ExtensionMethods
{
          public static StringBuilder  replace(this StringBuilder Sb1,string input, 
          Func<string> anonymos)
          {
               return Sb1.Replace(input, anonymos.Invoke());
          }
}

и вам нужно вызвать метод замены расширения, подобный этому

        StringBuilder s1 = new StringBuilder();
        s1.Append("hai");
        s1.replace("hai", () =>
        {
            return "bb";
        });

надеюсь это поможет.

person RameshVel    schedule 13.10.2009

Это правильный синтаксис для возврата строки из анонимного метода. Ваша проблема в другом - вы пытаетесь передать анонимный метод StringBuilder.Replace() в качестве второго аргумента, где он ожидает строку.

Зачем ты вообще это делаешь?

person ripper234    schedule 13.10.2009

Я считаю, что вам нужно расширить существующий метод.

Пожалуйста, перейдите по этой ссылке --> http://msdn.microsoft.com/en-us/library/bb383977.aspx

person solairaja    schedule 13.10.2009

Вы можете сделать следующее:

StringBuilder sb = new StringBuilder();
Func<string> func = delegate()
{
    return "HELLO";
};
sb.Replace("", func());

Хотя я не вижу в этом смысла...

person Maximilian Mayerl    schedule 13.10.2009
comment
Вы упускаете суть, он хочет создать метод расширения, который позволяет это, его анонимный метод был в порядке. - person Yannick Motton; 13.10.2009
comment
Ну, он написал, что тоже хочет создать метод расширения, поэтому я подумал, что это просто какой-то второй вопрос. - person Maximilian Mayerl; 13.10.2009

Немного неясно, как вы собираетесь это использовать - поскольку пример, который вы опубликовали, тривиален, я должен спросить ts, есть ли какая-то конкретная причина, по которой он должен быть анонимным методом? Разве это не может быть просто обычный метод экземпляра?

person Martin Clarke    schedule 13.10.2009