[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
. Func
s는 값을 반환하지만 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);
}