c# - 플러그인 - 비주얼 스튜디오 진단 도구




C#의 숨겨진 기능? (20)

질문 에서 다음을 배운 후에 이것은 내 마음에 왔습니다.

where T : struct

C # 개발자는 모두 C #의 기본 사항을 알고 있습니다. 선언, 조건부, 루프, 연산자 등을 의미합니다.

우리 중 일부는 Generics , anonymous types , lambdas , LINQ 등과 같은 것들을 마스터했습니다.

그러나 C # 팬, 중독자, 전문가조차 거의 알지 못하는 C #의 가장 숨겨진 기능이나 요령은 무엇입니까?

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


키워드

속성

통사론

언어 특징

Visual Studio 기능

뼈대

방법 및 속성

  • KiwiBastard String.IsNullOrEmpty() 메소드
  • List.ForEach() 메소드
  • Will Dean의 BeginInvoke() , EndInvoke() 메소드
  • Nullable<T>.HasValueNullable<T>.Value 속성
  • John Sheehan의 GetValueOrDefault 메소드

팁 & 트릭

  • Andreas HR Nilsson의 이벤트 핸들러를위한 멋진 방법
  • John 대문자 비교
  • dp 의해 반영되지 않은 익명 유형에 액세스
  • Will 통해 컬렉션 속성을 느리게 인스턴스화하는 빠른 방법
  • roosteronacid JavaScript와 같은 익명 인라인 함수

다른


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

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

당신이 가지고 있다면

string s = @"cat
             dog
             fish"

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

cat
             dog
             fish

CLR을 통해 C #을 통해 :

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

동료가 비교하기 전에 항상 문자열을 대문자로 변경 한 적이 있습니다. 나는 왜 그가 소문자로 변환하는 것이 더 "자연 스럽다"고 느끼기 때문에 왜 그렇게하는지 궁금했습니다. 지금 책을 읽은 후 왜 그런지 알고 있습니다.


  1. ?? -통합 연산자
  2. using ( statement / directive )-Dispose를 호출하는 것 이상으로 사용할 수있는 훌륭한 키워드
  3. readonly -더 많이 사용해야 함
  4. netmodules-너무 나빠 Visual Studio에서 지원되지 않습니다

" yield "이 내 마음에 올 것이다. DefaultValueAttribute 와 같은 속성 중 일부는 또한 내가 좋아하는 것 중 하나입니다.

" var "키워드는 좀 더 잘 알려져 있지만 .NET 3.5 응용 프로그램에서도 사용할있습니다 (.NET 3.5 컴파일러사용하고 출력 2.0 코드로 설정 한 경우). 잘.

편집 : kokos, 지적 해 주셔서 감사합니다 ?? 연산자, 정말 유용합니다. (구체적으로 무시되는 것처럼) 구글에 대해 조금 어렵 기 때문에 다음은 해당 연산자에 대한 MSDN 문서 페이지입니다. ?? ??


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

Environment.FailFast()

그 밖의 모든 것

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();

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

private IList<Foo> _foo;

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

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

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()}

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

__makeref

__reftype

__refvalue

__arglist

이것은 문서화되지 않은 C # 키워드 (Visual Studio조차도 인식합니다!)로 제네릭 이전에보다 효율적인 권투 / 언 박싱을 위해 추가되었습니다. 그것들은 System.TypedReference 구조체와 함께 작동합니다.

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

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

가장 유용한 "숨김"기능은 수익률 반환 키워드입니다. 실제로 숨겨져 있지는 않지만 많은 사람들이 그것에 대해 알지 못합니다. LINQ는이 위에 구축되었습니다. 후드 아래에서 상태 머신을 생성하여 지연 실행 쿼리를 허용합니다. Raymond Chen은 최근에 내부의 세부 사항 에 대해 게시했습니다.


별명 제네릭 :

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

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

많은 장소에서 동일한 일반적인 크고 긴 복잡한 것을 사용할 때 사용하십시오.


일반 유형의 '기본'키워드 :

T t = default(T);

T가 참조 유형이면 'null'이되고, int이면 0이되고, 부울이면 false가됩니다.


일반적으로 속성이지만 대부분의 모든 DebuggerDisplay 몇 년을 절약합니다.


Rick Strahl에서 :

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

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

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의 관련 토론 과이 블로그 게시물 (및 가능한 단점)도 참조하십시오.


순수하고 안전한 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를 사용하여 추가하십시오.


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"

메소드에서 익명 유형을 리턴하고 반영없이 멤버에 액세스

// 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;
}

어쩌면 고급 기술은 아니지만 항상 나를 미치게하는 기술입니다.

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

다음과 같이 요약 될 수 있습니다.

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

@ Ed, 나는 nitpicking 이상이 아니기 때문에 이것을 게시하는 것에 대해 약간의 reticent입니다. 그러나 코드 샘플에서 다음을 지적합니다.

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의 내장에 대해 충분히 알지 못하지만 본능에 따르면 최대 두 가지 유형의 캐스트 작업을 최대 1로 줄이겠다 고 말합니다. 처리 은행을 어느 쪽이든 깨뜨릴 가능성은 거의 없습니다. 개인적으로 후자의 형식도 더 깨끗해 보입니다.


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

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

물론, 일부 명확성이 희생됩니다. 그러나 작동합니다!





hidden-features