[c#] C #에서 인라인 함수를 만드는 방법
Linq To XML을 사용하고 있습니다.
new XElement("Prefix", Prefix == null ? "" : Prefix)
하지만 공백, 특수 문자, 일부 계산 등을 제거하는 것과 같이 접두사를 xml에 추가하기 전에 일부 계산을 수행하고 싶습니다.
이 함수는 내 프로그램의 다른 부분에 도움이되지 않기 때문에 함수를 만들고 싶지 않지만 이것은 인라인 함수를 만드는 방법이 있습니까 ??
답변
예, C #은이를 지원합니다. 사용 가능한 여러 구문이 있습니다.
-
익명 메서드 가 C # 2.0에 추가되었습니다.
Func<int, int, int> add = delegate(int x, int y) { return x + y; }; Action<int> print = delegate(int x) { Console.WriteLine(x); } Action<int> helloWorld = delegate // parameters can be elided if ignored { Console.WriteLine("Hello world!"); } -
Lambda 는 C # 3.0의 새로운 기능이며 두 가지 유형으로 제공됩니다.
-
식 람다 :
Func<int, int, int> add = (int x, int y) => x + y; // or... Func<int, int, int> add = (x, y) => x + y; // types are inferred by the compiler -
문 람다 :
Action<int> print = (int x) => { Console.WriteLine(x); }; Action<int> print = x => { Console.WriteLine(x); }; // inferred types Func<int, int, int> add = (x, y) => { return x + y; };
-
-
C # 7.0에는 로컬 함수 가 도입되었습니다.
int add(int x, int y) => x + y; void print(int x) { Console.WriteLine(x); }
이 이러한 두 가지 종류가 기본적으로 있습니다 : Func와 Action. Funcs는 값을 반환하지만 Action그렇지 않습니다. a의 마지막 유형 매개 변수 Func는 반환 유형입니다. 나머지는 모두 매개 변수 유형입니다.
이름이 다른 유사한 유형이 있지만 인라인으로 선언하는 구문은 동일합니다. 이것의 예는 Comparison<T>, 대략 Func<T, T, int>.
Func<string, string, int> compare1 = (l,r) => 1;
Comparison<string> compare2 = (l, r) => 1;
Comparison<string> compare3 = compare1; // this one only works from C# 4.0 onwards
일반 메소드 인 것처럼 직접 호출 할 수 있습니다.
int x = add(23, 17); // x == 40
print(x); // outputs 40
helloWorld(x); // helloWorld has one int parameter declared: Action<int>
// even though it does not make any use of it.
답변
답변
귀하의 질문에 대한 대답은 “인라인 기능”이 의미하는 바에 따라 예 및 아니오입니다. C ++ 개발에서 사용되는 것과 같은 용어를 사용하는 경우 대답은 아니오입니다. 그렇게 할 수 없습니다. 심지어 람다 식도 함수 호출입니다. C #에서 함수 선언을 대체하기 위해 인라인 람다 식을 정의 할 수 있다는 것은 사실이지만 컴파일러는 여전히 익명 함수를 생성합니다.
다음은 이것을 테스트하는 데 사용한 매우 간단한 코드입니다 (VS2015).
static void Main(string[] args)
{
Func<int, int> incr = a => a + 1;
Console.WriteLine($"P1 = {incr(5)}");
}
컴파일러는 무엇을 생성합니까? 실제로 생성 된 IL 어셈블리를 보여주는 ILSpy라는 멋진 도구를 사용했습니다. 보세요 (많은 수업 설정 항목을 생략했습니다)
이것이 주요 기능입니다.
IL_001f: stloc.0
IL_0020: ldstr "P1 = {0}"
IL_0025: ldloc.0
IL_0026: ldc.i4.5
IL_0027: callvirt instance !1 class [mscorlib]System.Func`2<int32, int32>::Invoke(!0)
IL_002c: box [mscorlib]System.Int32
IL_0031: call string [mscorlib]System.String::Format(string, object)
IL_0036: call void [mscorlib]System.Console::WriteLine(string)
IL_003b: ret
IL_0026 및 IL_0027 줄이 보이십니까? 이 두 명령어는 숫자 5를로드하고 함수를 호출합니다. 그런 다음 IL_0031 및 IL_0036 형식을 지정하고 결과를 인쇄합니다.
다음은 호출 된 함수입니다.
.method assembly hidebysig
instance int32 '<Main>b__0_0' (
int32 a
) cil managed
{
// Method begins at RVA 0x20ac
// Code size 4 (0x4)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4.1
IL_0002: add
IL_0003: ret
} // end of method '<>c'::'<Main>b__0_0'
정말 짧은 기능이지만 기능입니다.
최적화를 위해 노력할 가치가 있습니까? 아니. 1 초에 수천 번 호출하고 있지만 성능이 그렇게 중요하다면 C / C ++로 작성된 네이티브 코드를 호출하여 작업을 수행하는 것을 고려해야합니다.
내 경험상 가독성과 유지 보수성은 몇 마이크로 초의 속도 향상을 최적화하는 것보다 거의 항상 더 중요합니다. 함수를 사용하여 코드를 읽기 쉽게 만들고 변수 범위를 제어하고 성능에 대해 걱정하지 마십시오.
“조기 최적화는 프로그래밍에서 모든 악 (또는 적어도 대부분)의 근원입니다.” -도널드 크 누스
“올바르게 실행되지 않는 프로그램은 빠르게 실행할 필요가 없습니다.”-Me
답변
답변
하나의 매개 변수가있는 메소드를 캡슐화하고 TResult 매개 변수에 지정된 유형의 값을 리턴하는 Func 를 사용할 수 있습니다 .
void Method()
{
Func<string,string> inlineFunction = source =>
{
// add your functionality here
return source ;
};
// call the inline function
inlineFunction("prefix");
}
답변
Inside 메서드뿐만 아니라 클래스 내부에서도 사용할 수 있습니다.
class Calculator
{
public static int Sum(int x,int y) => x + y;
public static Func<int, int, int> Add = (x, y) => x + y;
public static Action<int,int> DisplaySum = (x, y) => Console.WriteLine(x + y);
}
답변
