etc./StackOverFlow

C#의 숨겨진 기능? [닫은]

청렴결백한 만능 재주꾼 2022. 3. 22. 11:03
반응형

질문자 :Community Wiki


이 질문 에서 다음을 배운 후 이것이 내 마음에 떠올랐습니다.

 where T : struct

우리 C# 개발자는 모두 C#의 기초를 알고 있습니다. 선언, 조건, 루프, 연산자 등을 의미합니다.

우리 중 일부는 제네릭 , 익명 유형 , 람다 , LINQ , ...

그러나 C# 팬, 중독자, 전문가도 거의 모르는 C#의 가장 숨겨진 기능이나 트릭은 무엇입니까?

지금까지 공개된 기능은 다음과 같습니다.


키워드

속성

통사론

언어 기능

비주얼 스튜디오 기능

뼈대

방법 및 속성

팁 & 트릭

  • Andreas HR Nilsson의 이벤트 핸들러를 위한 좋은 방법
  • John의 대문자 비교
  • dp에 의한 리플렉션 없이 익명 유형에 액세스
  • Will이 컬렉션 속성을 느리게 인스턴스화하는 빠른 방법
  • roosteronacid의 JavaScript와 유사한 익명 인라인 함수

다른



System.IO.Path.Combine() 을 실제로 사용해야 하는 정도로 사용하는 사람을 본 적이 없습니다. 사실, 전체 Path 클래스는 정말 유용하지만 아무도 사용하지 않습니다!

모든 프로덕션 앱에는 다음 코드가 포함되어 있지 않아도 됩니다.

 string path = dir + "\\" + fileName;

Community Wiki

람다 및 형식 유추 는 과소 평가됩니다. 람다는 다음과 같이 여러 명령문을 가질 수 있으며 다음 과 같이 자동으로 호환되는 대리자 객체로 두 배가 됩니다(서명이 일치하는지 확인하십시오).

 Console.CancelKeyPress += (sender, e) => { Console.WriteLine("CTRL+C detected!\n"); e.Cancel = true; };

new CancellationEventHandler sendere 유형을 지정할 필요도 없으며 이벤트에서 유추할 수 있습니다. 이것이 매개변수 유형을 지정해야 delegate (blah blah) 를 작성하는 것이 덜 번거로운 이유입니다.

람다는 아무 것도 반환할 필요가 없으며 유형 추론은 이와 같은 맥락에서 매우 강력합니다.

그리고 BTW, 함수형 프로그래밍 의미에서 Lambda를 만드는 Lambda 를 항상 반환할 수 있습니다. 예를 들어 다음은 Button.Click 이벤트를 처리하는 람다를 만드는 람다입니다.

 Func<int, int, EventHandler> makeHandler = (dx, dy) => (sender, e) => { var btn = (Button) sender; btn.Top += dy; btn.Left += dx; }; btnUp.Click += makeHandler(0, -1); btnDown.Click += makeHandler(0, 1); btnLeft.Click += makeHandler(-1, 0); btnRight.Click += makeHandler(1, 0);

연결에 유의하십시오. (dx, dy) => (sender, e) =>

그래서 저는 함수형 프로그래밍 수업을 수강하게 되어 기쁩니다 :-)

C의 포인터 외에 배워야 할 또 다른 기본 사항이라고 생각합니다 :-)


Community Wiki

릭 스트랄에서 :

당신은 체인 수 ?? 연산자를 사용하여 많은 null 비교를 수행할 수 있습니다.

 string result = value1 ?? value2 ?? value3 ?? String.Empty;

Community Wiki

별칭 제네릭:

 using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

Dictionary<string, Dictionary<string, List<string>>> 대신 ASimpleName 을 사용할 수 있습니다.

많은 곳에서 동일한 일반 크고 길고 복잡한 것을 사용할 때 사용하십시오.


Community Wiki

C#을 통해 CLR에서 :

문자열을 정규화할 때 ToLowerInvariant 대신 ToUpperInvariant를 사용하는 것이 좋습니다. Microsoft는 대문자 비교를 수행하기 위해 코드를 최적화 했기 때문입니다.

한 번 내 동료가 비교하기 전에 항상 문자열을 대문자로 변경했던 것을 기억합니다. 나는 항상 소문자로 먼저 변환하는 것이 더 "자연스럽다"고 느끼기 때문에 그가 왜 그렇게 하는지 궁금했습니다. 책을 읽고 나서 이제야 그 이유를 알았습니다.


Community Wiki

내가 가장 좋아하는 트릭은 null 병합 연산자 와 괄호를 사용하여 컬렉션을 자동으로 인스턴스화하는 것입니다.

 private IList<Foo> _foo; public IList<Foo> ListOfFoo { get { return _foo ?? (_foo = new List<Foo>()); } }

Community Wiki

null 이벤트 핸들러 확인 피하기

선언 시 이벤트에 빈 대리자를 추가하여 이벤트를 호출하기 전에 항상 null이 있는지 확인할 필요가 없도록 하는 것이 좋습니다. 예시:

 public delegate void MyClickHandler(object sender, string myValue); public event MyClickHandler Click = delegate {}; // add empty delegate!

당신이 이것을 하게 하십시오

 public void DoSomething() { Click(this, "foo"); }

이 대신

 public void DoSomething() { // Unnecessary! MyClickHandler click = Click; if (click != null) // Unnecessary! { click(this, "foo"); } }

이 주제(및 가능한 단점)에 대한 이 관련 토론Eric Lippert의 이 블로그 게시물 도 참조하십시오.


Community Wiki

다른 모든 것, 플러스

1) 암시적 제네릭(클래스가 아닌 메서드에만 있는 이유는 무엇입니까?)

 void GenericMethod<T>( T input ) { ... } //Infer type, so GenericMethod<int>(23); //You don't need the <>. GenericMethod(23); //Is enough.

2) 매개변수가 하나인 간단한 람다:

 x => x.ToString() //simplify so many calls

3) 익명 유형 및 이니셜라이저:

 //Duck-typed: works with any .Add method. var colours = new Dictionary<string, string> { { "red", "#ff0000" }, { "green", "#00ff00" }, { "blue", "#0000ff" } }; int[] arrayOfInt = { 1, 2, 3, 4, 5 };

다른 것:

4) 자동 속성은 다른 범위를 가질 수 있습니다.

 public int MyId { get; private set; }

상기시켜주신 @pzycoman님 감사합니다.

5) 네임스페이스 별칭(이 특정 구분이 필요할 가능성이 없음):

 using web = System.Web.UI.WebControls; using win = System.Windows.Forms; web::Control aWebControl = new web::Control(); win::Control aFormControl = new win::Control();

Community Wiki

나는 꽤 오랫동안 "as" 키워드를 몰랐다.

 MyClass myObject = (MyClass) obj;

 MyClass myObject = obj as MyClass;

두 번째는 obj가 MyClass가 아닌 경우 클래스 캐스트 예외를 throw하는 대신 null을 반환합니다.


Community Wiki

내가 좋아하는 두 가지는 자동 속성이므로 코드를 훨씬 더 축소할 수 있습니다.

 private string _name; public string Name { get { return _name; } set { _name = value; } }

된다

 public string Name { get; set;}

또한 객체 이니셜라이저:

 Employee emp = new Employee(); emp.Name = "John Smith"; emp.StartDate = DateTime.Now();

된다

 Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}

Community Wiki

제네릭 유형의 'default' 키워드:

 T t = default(T);

결과는 T가 참조 유형이면 'null'이고 int이면 0이고 부울이면 false입니다.


Community Wiki

일반적으로 속성이지만 대부분의 DebuggerDisplay . 몇 년을 절약할 수 있습니다.


Community Wiki

@는 컴파일러에게 문자열의 모든 이스케이프 문자를 무시하도록 지시합니다.

이것을 명확히 하고 싶었습니다... 이스케이프 문자를 무시하라고 지시하는 것이 아니라 실제로 컴파일러에게 문자열을 리터럴로 해석하도록 지시합니다.

당신이 가지고 있다면

 string s = @"cat dog fish"

실제로 다음과 같이 인쇄됩니다(들여쓰기에 사용되는 공백도 포함됨).

 cat dog fish

Community Wiki

저는 C#(.NET 3.5)에서 가장 잘 알려지지 않고 잘 알려지지 않은 기능 중 하나가 특히 Generics 및 Lambda와 결합된 경우 Expression Trees라고 생각합니다. 이것은 NInject 및 Moq와 같은 최신 라이브러리에서 사용하는 API 생성에 대한 접근 방식입니다.

예를 들어 API에 메서드를 등록하고 해당 API가 메서드 이름을 가져와야 한다고 가정해 보겠습니다.

이 클래스가 주어졌을 때:

 public class MyClass { public void SomeMethod() { /* Do Something */ } }

이전에는 개발자가 문자열과 유형(또는 주로 문자열 기반)을 사용하여 이 작업을 수행하는 것을 보는 것이 매우 일반적이었습니다.

 RegisterMethod(typeof(MyClass), "SomeMethod");

글쎄, 그것은 강한 타이핑이 없기 때문에 짜증난다. "SomeMethod"의 이름을 바꾸면 어떻게 됩니까? 그러나 이제 3.5에서는 강력한 형식으로 이 작업을 수행할 수 있습니다.

 RegisterMethod<MyClass>(cl => cl.SomeMethod());

RegisterMethod 클래스에서 다음 Expression<Action<T>> 사용합니다.

 void RegisterMethod<T>(Expression<Action<T>> action) where T : class { var expression = (action.Body as MethodCallExpression); if (expression != null) { // TODO: Register method Console.WriteLine(expression.Method.Name); } }

이것이 제가 지금 Lambda와 Expression Tree를 사랑하는 큰 이유 중 하나입니다.


Community Wiki

" 수익률 "이 떠오를 것입니다. [DefaultValue()] 와 같은 속성 중 일부는 내가 즐겨찾는 속성이기도 합니다.

" var " 키워드는 조금 더 알려져 있지만 .NET 2.0 응용 프로그램에서도 사용할 수 있다는 점( .NET 3.5 컴파일러 를 사용하고 2.0 코드를 출력하도록 설정하는 한)은 잘 알려지지 않은 것 같습니다. 잘.

편집: kokos, 지적해 주셔서 감사합니다 ?? 운영자, 정말 유용합니다. ??는 무시하기 때문에 Google에서 검색하기가 약간 어렵기 때문에 해당 연산자에 대한 MSDN 설명서 페이지는 다음과 같습니다 . ?? 연산자(C# 참조)


Community Wiki

대부분의 C# 개발자는 'nullable' 유형에 대해 알지 못하는 경향이 있습니다. 기본적으로 null 값을 가질 수 있는 프리미티브.

 double? num1 = null; double num2 = num1 ?? -100;

nullable double num1 을 null로 설정한 다음 일반 double num2num1 또는 num1 이 null인 경우 -100으로 설정합니다.

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

Nullable 유형에 대해 한 가지 더:

 DateTime? tmp = new DateTime(); tmp = null; return tmp.ToString();

그것은 String.Empty를 반환합니다. 자세한 내용은 링크를 확인하세요


Community Wiki

다음은 문서화되지 않은 C# 키워드의 형태로 숨겨진 흥미로운 C# 기능입니다.

 __makeref __reftype __refvalue __arglist

이는 제네릭 이전에 보다 효율적인 boxing/unboxing을 위해 추가된 문서화되지 않은 C# 키워드(Visual Studio에서도 인식합니다!)입니다. System.TypedReference 구조체와 함께 작동합니다.

가변 길이 매개변수 목록에 사용되는 __arglist도 있습니다.

사람들이 잘 알지 못하는 한 가지는 System.WeakReference 입니다. 개체를 추적하지만 여전히 가비지 수집기가 개체를 수집할 수 있도록 하는 매우 유용한 클래스입니다.

가장 유용한 "숨겨진" 기능은 yield return 키워드입니다. 딱히 숨겨져 있지는 않지만 많은 사람들이 그것에 대해 모르고 있습니다. LINQ는 이 위에 구축되었습니다. 후드 아래에 상태 머신을 생성하여 지연 실행 쿼리를 허용합니다. Raymond Chen은 최근에 내부의 껄끄러운 세부 사항 에 대해 게시했습니다.


Community Wiki

순수하고 안전한 C#의 공용체(C++ 공유 메모리 종류)

안전하지 않은 모드와 포인터에 의존하지 않고 클래스 멤버가 클래스/구조체에서 메모리 공간을 공유하도록 할 수 있습니다. 다음 클래스가 주어졌을 때:

 [StructLayout(LayoutKind.Explicit)] public class A { [FieldOffset(0)] public byte One; [FieldOffset(1)] public byte Two; [FieldOffset(2)] public byte Three; [FieldOffset(3)] public byte Four; [FieldOffset(0)] public int Int32; }

Int32 필드를 조작하여 바이트 필드의 값을 수정할 수 있으며 그 반대의 경우도 마찬가지입니다. 예를 들어 이 프로그램은 다음과 같습니다.

 static void Main(string[] args) { A a = new A { Int32 = int.MaxValue }; Console.WriteLine(a.Int32); Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four); a.Four = 0; a.Three = 0; Console.WriteLine(a.Int32); }

다음을 출력합니다.

 2147483647 FF FF FF 7F 65535

System.Runtime.InteropServices를 사용하여 추가하기만 하면 됩니다.


Community Wiki

키워드인 변수 이름에 @를 사용합니다.

 var @object = new object(); var @string = ""; var @if = IpsoFacto();

Community Wiki

finally 블록이나 종료자를 호출하지 않고 프로그램을 종료하려면 FailFast를 사용하십시오.

 Environment.FailFast()

Community Wiki

메서드에서 익명 형식을 반환하고 리플렉션 없이 멤버에 액세스합니다.

 // Useful? probably not. private void foo() { var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) }); Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges); } object GetUserTuple() { return new { Name = "dp", Badges = 5 }; } // Using the magic of Type Inference... static T AnonCast<T>(object obj, T t) { return (T) obj; }

Community Wiki

다음은 정규식 및 파일 경로에 대한 유용한 정보입니다.

 "c:\\program files\\oldway" @"c:\program file\newway"

@는 컴파일러에게 문자열의 모든 이스케이프 문자를 무시하도록 지시합니다.


Community Wiki

믹신. 기본적으로 여러 클래스에 기능을 추가하고 싶지만 모든 클래스에 대해 하나의 기본 클래스를 사용할 수 없는 경우 각 클래스가 인터페이스를 구현하도록 합니다(멤버 없음). 그런 다음 인터페이스에 대한 확장 메서드를 작성합니다.

 public static DeepCopy(this IPrototype p) { ... }

물론 일부 명확성은 희생됩니다. 하지만 작동합니다!


Community Wiki

왜 누군가가 Nullable<bool>을 사용하고 싶어하는지 확실하지 않습니다. :-)

참, 거짓, FileNotFound ?


Community Wiki

이것은 이름이 잘못 지정된 만큼 "숨겨진" 것이 아닙니다.

"map", "reduce" 및 "filter" 알고리즘에 많은 주의를 기울였습니다. 대부분의 사람들이 깨닫지 못하는 것은 .NET 3.5가 이러한 세 가지 알고리즘을 모두 추가했지만 LINQ의 일부라는 사실을 기반으로 매우 SQL 같은 이름을 부여했다는 것입니다.

"지도" => 선택
데이터를 한 형식에서 다른 형식으로 변환

"감소" => 집계
값을 단일 결과로 집계

"필터" => 어디에
기준에 따라 데이터 필터링

LINQ를 사용하여 반복 및 조건문을 사용하는 컬렉션에 대한 인라인 작업을 수행하는 기능은 매우 유용할 수 있습니다. 모든 LINQ 확장 메서드가 코드를 훨씬 더 간결하고 유지 관리하기 쉽게 만드는 방법을 배울 가치가 있습니다.


Community Wiki

Environment.NewLine

시스템 독립 줄 바꿈의 경우.


Community Wiki

String.Format 표현식 내에서 중괄호를 사용하려는 경우...

 int foo = 3; string bar = "blind mice"; String.Format("{{I am in brackets!}} {0} {1}", foo, bar); //Outputs "{I am in brackets!} 3 blind mice"

Community Wiki

  1. ?? - 병합 연산자
  2. using ( statement / 지시문 ) - Dispose를 호출하는 것 이상으로 사용할 수 있는 훌륭한 키워드
  3. 읽기 전용 - 더 많이 사용해야 합니다.
  4. netmodules - Visual Studio에서 지원하지 않는 것이 너무 아쉽습니다.

Community Wiki

@Ed, 나는 이것이 nitpicking보다 조금 더 많기 때문에 이것을 게시하는 것에 대해 약간 과묵합니다. 그러나 귀하의 코드 샘플에서 다음과 같이 지적합니다.

 MyClass c; if (obj is MyClass) c = obj as MyClass

'is'를 사용하려는 경우 'as'를 사용하여 안전한 캐스트를 사용하는 이유는 무엇입니까? obj가 늪지 표준 캐스트인 실제로 MyClass임을 확인한 경우:

 c = (MyClass)obj

...절대 실패하지 않습니다.

마찬가지로 다음과 같이 말할 수 있습니다.

 MyClass c = obj as MyClass; if(c != null) { ... }

나는 .NET의 내부에 대해 확신할 만큼 충분히 알지 못하지만, 내 본능에 따르면 이것이 최대 2개의 유형 캐스트 작업을 최대 1개로 줄일 수 있습니다. 어느 쪽이든 처리 은행을 깨뜨릴 가능성은 거의 없습니다. 개인적으로 후자의 형태도 더 깔끔해 보인다고 생각합니다.


Community Wiki

고급 기술은 아니지만 항상 나를 미치게 만드는 기술은 다음과 같습니다.

 if (x == 1) { x = 2; } else { x = 3; }

다음과 같이 압축할 수 있습니다.

 x = (x==1) ? 2 : 3;

Community Wiki

출처 : http:www.stackoverflow.com/questions/9033/hidden-features-of-c

반응형