최근에 DateTime
객체로 작업하고 있었고 다음과 같이 썼습니다.
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
에 대한 인텔리전스 문서에 AddDays()
따르면 날짜에 날짜를 추가하지만 날짜가 추가되지 않은 날짜를 반환 하므로 다음과 같이 작성해야합니다.
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
이것은 전에 여러 번 물린 적이 있기 때문에 최악의 C # gotcha를 카탈로그 화하는 것이 유용 할 것이라고 생각했습니다.
답변
private int myVar;
public int MyVar
{
get { return MyVar; }
}
블 람모. 스택 추적없이 앱이 충돌합니다. 항상 일어난다.
( 게터에서 MyVar
소문자 대신 통지 자본 myVar
)
답변
Type.GetType
내가 많은 사람들을 물린 것을 보았습니다 Type.GetType(string)
. 그들은 왜 자신의 어셈블리에서 유형에 대해 작동하는지 궁금 System.String
하지만 일부 유형은 그렇지 않지만 궁금합니다 System.Windows.Forms.Form
. 답은 현재 어셈블리와에서만 볼 수 있다는 것입니다 mscorlib
.
익명의 방법
C # 2.0은 익명의 메서드를 도입하여 다음과 같은 불쾌한 상황을 초래했습니다.
using System;
using System.Threading;
class Test
{
static void Main()
{
for (int i=0; i < 10; i++)
{
ThreadStart ts = delegate { Console.WriteLine(i); };
new Thread(ts).Start();
}
}
}
그게 무엇을 인쇄합니까? 글쎄, 그것은 전적으로 일정에 달려 있습니다. 10 개의 숫자를 인쇄하지만 0, 1, 2, 3, 4, 5, 6, 7, 8, 9는 인쇄하지 않을 것입니다. 문제는 i
변수가 델리게이트 생성 시점의 값이 아니라 캡처 된 변수라는 것입니다. 올바른 범위의 추가 로컬 변수를 사용하면 쉽게 해결할 수 있습니다.
using System;
using System.Threading;
class Test
{
static void Main()
{
for (int i=0; i < 10; i++)
{
int copy = i;
ThreadStart ts = delegate { Console.WriteLine(copy); };
new Thread(ts).Start();
}
}
}
반복자 블록의 지연된 실행
이 “가난한 사람의 단위 테스트”는 통과되지 않습니다-왜 안되죠?
using System;
using System.Collections.Generic;
using System.Diagnostics;
class Test
{
static IEnumerable<char> CapitalLetters(string input)
{
if (input == null)
{
throw new ArgumentNullException(input);
}
foreach (char c in input)
{
yield return char.ToUpper(c);
}
}
static void Main()
{
// Test that null input is handled correctly
try
{
CapitalLetters(null);
Console.WriteLine("An exception should have been thrown!");
}
catch (ArgumentNullException)
{
// Expected
}
}
}
대답은 CapitalLetters
반복기의 MoveNext()
메소드가 처음 호출 될 때까지 코드 소스 내의 코드가 실행되지 않는다는 것 입니다.
내 brainteasers 페이지 에 다른 이상한 점이 있습니다.
답변
예외 다시 던지기
많은 새로운 개발자를 얻는 문제는 다시 던지기 예외 의미입니다.
많은 시간이 다음과 같은 코드를 본다
catch(Exception e)
{
// Do stuff
throw e;
}
문제는 스택 추적을 지우고 문제 진단을 훨씬 어렵게하여 예외가 발생한 위치를 추적 할 수 없다는 것입니다.
올바른 코드는 인수가없는 throw 문입니다.
catch(Exception)
{
throw;
}
또는 예외를 다른 것으로 랩핑하고 내부 예외를 사용하여 원래 스택 추적을 가져옵니다.
catch(Exception e)
{
// Do stuff
throw new MySpecialException(e);
}
답변
하이젠 베르크 시계 창
다음과 같이 주문형 작업을 수행하는 경우 심하게 물릴 수 있습니다.
private MyClass _myObj;
public MyClass MyObj {
get {
if (_myObj == null)
_myObj = CreateMyObj(); // some other code to create my object
return _myObj;
}
}
이제 이것을 사용하는 다른 코드가 있다고 가정 해 봅시다.
// blah
// blah
MyObj.DoStuff(); // Line 3
// blah
이제 CreateMyObj()
메소드 를 디버그하려고합니다 . 따라서 코드에 들어가기 위해 위의 3 행에 중단 점을 두십시오. 좋은 측정을 위해 위의 줄에 중단 점을 지정하고 자체에 _myObj = CreateMyObj();
중단 점을 배치하십시오 CreateMyObj()
.
코드는 3 행에서 중단 점에 도달합니다. 코드로 들어갑니다. _myObj
분명히 null 이기 때문에 조건부 코드를 입력 할 것으로 예상됩니다 . 어 … 그래서 … 왜 조건을 건너 뛰고 바로 갔 return _myObj
습니까?! _myObj 위로 마우스를 가져 가면 실제로 가치가 있습니다! 어떻게 된거 지?!
대답은 “감시”창이 열려 있기 때문에 IDE가 값을 얻었 기 때문입니다. 특히 “자동”감시 창은 현재 또는 이전 실행 라인과 관련된 모든 변수 / 속성의 값을 표시합니다. Line 3에서 중단 점에 도달하면 감시 창에서 중단 점을 무시하고MyObj
장면 뒤의 가치를 알고 자한다면 중단 점을 무시하고 그 가치에 MyObj
대한 통화를 계산 CreateMyObj()
했습니다. _myObj! 값을 설정합니다
이것이 제가 이것을 하이젠 버그 감시 창이라고 부르는 이유입니다-당신은 그 값에 영향을 미치지 않으면 서 그 값을 관찰 할 수 없습니다 …
고차!
편집 -@ChristianHayter의 의견은이 문제에 대한 효과적인 해결 방법처럼 보이기 때문에 주요 답변에 포함될 가치가 있다고 생각합니다. 그래서 당신은 게으른로드 속성이있을 때마다 …
[DebuggerBrowsable (DebuggerBrowsableState.Never)] 또는 [DebuggerDisplay ( “<loaded on demand>”)]로 속성을 장식하십시오. – 크리스티안 헤이 터
답변
나를 데려 오는 또 다른 시간이 있습니다.
static void PrintHowLong(DateTime a, DateTime b)
{
TimeSpan span = a - b;
Console.WriteLine(span.Seconds); // WRONG!
Console.WriteLine(span.TotalSeconds); // RIGHT!
}
TimeSpan.Seconds 는 시간 범위의 초 부분입니다 (2 분 0 초의 초 값은 0 임).
TimeSpan.TotalSeconds 는 초 단위로 측정 된 전체 시간 범위입니다 (2 분은 총 초 값 120).
답변
이벤트를 후크 해제하지 않았기 때문에 메모리 누수가 발생합니다.
이것은 심지어 내가 아는 선임 개발자들을 사로 잡았습니다.
많은 것들이 포함 된 WPF 양식을 상상해 보시고 어딘가에서 이벤트를 구독하십시오. 구독을 취소하지 않으면 양식을 닫고 참조 해제 한 후에 전체 양식이 메모리에 보관됩니다.
내가 본 문제는 WPF 양식에서 DispatchTimer를 만들고 Tick 이벤트를 구독하는 것이라고 생각합니다. 타이머에서-=를 수행하지 않으면 양식에서 메모리가 누출됩니다!
이 예제에서 테어 다운 코드는
timer.Tick -= TimerTickEventHandler;
WPF 양식 내에 DispatchTimer의 인스턴스를 만들었으므로 특히 까다로워서 가비지 수집 프로세스에서 처리하는 내부 참조라고 생각할 것입니다 … 불행히도 DispatchTimer는 정적 인 내부 구독 및 서비스 목록을 사용합니다. UI 스레드에 대한 요청이므로 정적 클래스에서 참조를 ‘소유’합니다.
답변
MSDN에서 동작이 명확하게 작성 되었기 때문에 실제로 문제가되지는 않지만 반 직관적 인 것으로 나타났기 때문에 목이 부러졌습니다.
Image image = System.Drawing.Image.FromFile("nice.pic");
이 사람 "nice.pic"
은 이미지가 폐기 될 때까지 파일을 잠근 상태로 둡니다 . 내가 직면했을 때 나는 아이콘을 즉석에서로드하는 것이 좋았지 만 수십 개의 열려 있고 잠겨있는 파일로 끝나는 것을 처음에는 알지 못했습니다! 이미지는 파일이로드 된 위치를 추적합니다 …
이것을 해결하는 방법? 나는 한 명의 라이너가 일을 할 것이라고 생각했다. 에 대한 추가 매개 변수가 필요 FromFile()
했지만 아무것도 없었으므로 이것을 썼습니다 …
using (Stream fs = new FileStream("nice.pic", FileMode.Open, FileAccess.Read))
{
image = System.Drawing.Image.FromStream(fs);
}