#c#
#c# #методы
Вопрос:
Я создаю библиотеку C # с некоторым повторно используемым кодом и пытался создать метод внутри метода. У меня есть такой метод:
public static void Method1()
{
// Code
}
Что я хотел бы сделать, так это:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Тогда я мог бы выбрать либо Method1.Method2
или Method1.Method3
. Очевидно, что компилятор недоволен этим, любая помощь очень ценится. Спасибо.
Комментарии:
1. Как концепция метода внутри метода будет работать в C #? Последний раз, когда я когда-либо видел определения вложенных функций / методов, был в PHP и JavaScript, но они предназначались для создания функций верхнего уровня «на лету».
2. поместите два метода в статический класс.
3. Чего вы хотите достичь с помощью этого?
4. Легко, вы можете вызвать его только из этого метода. Delphi поддерживает его.
5. В Delphi вы можете это сделать, но вложенные методы будут «частными», и только родительский метод сможет получить к нему доступ. В любом случае я очень скучаю по этой функции delphi / pascal, чтобы получить более чистый / организованный код.
Ответ №1:
Если под вложенным методом вы подразумеваете метод, который вызывается только внутри этого метода (например, в Delphi), вы могли бы использовать делегаты.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i ; });
int test = function(6);
}
Комментарии:
1. удобная ссылка для справки: msdn.microsoft.com/en-us/library/bb549151 (v = против 110).aspx
2. Я люблю делегатов, которые делают жизнь такой легкой… О, это должно быть ответом .. спасибо
3. это решение представляет собой определенный способ иметь вложенную функцию в c #. обратитесь к Википедии : en.wikipedia.org/wiki/Nested_function
4. По сути, это только что созданная лямбда-функция, не так ли?
Ответ №2:
Да, когда C# 7.0
он будет выпущен, локальные функции позволят вам это сделать. Вы сможете иметь метод внутри метода как:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName GetFamilyName(userId);
return fullName;
}
Обратите внимание, что public
(и подобные модификаторы) не поддерживаются руководством по программированию на C #:
Поскольку все локальные функции являются частными, включая модификатор доступа, такой как ключевое слово private, генерирует ошибку компилятора CS0106, «
Комментарии:
1. это полезно знать. возможно ли в этом примере использовать значение userId внутри вложенной функции GetFamilyName(), не передавая его в качестве параметра?
2. @symbiont: Да, аргументы (и локальные переменные) основной функции видны локальной (аналогично Delphi). Смотрите второй пример на изображении в infoworld.com/article/3182416/application-development /…
Ответ №3:
Этот ответ был написан до выхода C # 7. С помощью C # 7 вы можете писать локальные методы.
Нет, вы не можете этого сделать. Вы могли бы создать вложенный класс:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
Затем вы бы вызвали:
ContainingClass.NestedClass.Method2();
или
ContainingClass.NestedClass.Method3();
Однако я бы не рекомендовал это. Обычно иметь общедоступные вложенные типы — плохая идея.
Можете ли вы рассказать нам больше о том, чего вы пытаетесь достичь? Вполне может быть лучший подход.
Комментарии:
1. Я хотел вызвать метод, а затем иметь варианты того, что делать с кодом. Например, я передаю методу строковый аргумент, затем я мог бы вызвать любой из 2 вложенных методов в зависимости от того, что я хотел сделать со строкой, возможно, один метод преобразует в int, другой в double, что-то в этом роде. Спасибо
2. @BaliC: я бы, вероятно, сделал это с помощью отдельных частных методов. Вы могли бы использовать анонимные функции в общедоступном методе, но просто сделать их частными и документировать предполагаемое использование, вероятно, было бы проще.
3. Спасибо, вот в чем мне нужна была помощь, я не был уверен, каким путем это сделать.
4. В примере не показана основная функция pascal, подобная вложенным функциям, а именно доступ к родительским переменным из вложенной функции? Разложение его на другие объекты тогда бесполезно, поскольку вам либо придется снова передавать все по параметрам
5. @Andy: Ну, это почти так — но это, конечно, было не в 2011 году 🙂
Ответ №4:
Вы можете определить делегатов в своем методе с помощью полного кода и вызвать их, если хотите.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
Всегда есть альтернатива использованию вложенного класса внутри класса, который не будет виден извне, и вызову его методы, например:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
Ответ №5:
Начиная с C # 7.0, вы можете это сделать:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
Это называется локальными функциями, это именно то, что вы искали.
Я взял пример отсюда, но дополнительную информацию можно найти здесь и здесь .
Ответ №6:
Почему вы не используете классы?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Теперь вы можете получить доступ к методу через
Helper.MethodA();
Ответ №7:
Более старый поток, но в C # есть концепция вложенных функций
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue = total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Комментарии:
1. Возможно, стоит упомянуть, когда это было добавлено как IIRC, это было добавлено достаточно недавно, чтобы оно могло быть доступно не во всех средах. Также
calcArithmatic
может быть не лучшим именем для функции, которая возвращает функцию и не выполняет фактическую арифметику.2. Я думаю, что это справедливо для обоих пунктов. Я обновил имя метода.
Ответ №8:
Вы почти там
public static void Method1()
должно быть
public static class Method1{}
Ответ №9:
Разве вы не хотите вместо этого использовать вложенный класс?
Тем не менее, вы, похоже, не соблюдаете принцип единой ответственности, потому что хотите, чтобы один метод выполнял более одной задачи одновременно.
Ответ №10:
Почему бы вам просто не запустить метод в другом
public void M1() { ДЕЛАТЬ ВЕЩИ}
public void M1() { ДЕЛАТЬ ВЕЩИ M1(); }
Комментарии:
1. Это не только не приведет к компиляции, но и вызовет переполнение стека, если это произойдет. Это НЕ очень хорошая идея.