잊지 않겠습니다.

Complier warning may not be benign

Compiler에서의 경고를 무시하지 말아라. Compiler에서의 경고는 모두다 없애는 것이 가장 우선되는 일이 된다.

Treat warnings as errors option을 활성화시키고 나서 compile하는 것이 좋다.

모든 project의 수행시에, 이 옵션을 활성화 시키고 나서 시작하는 것이 유용하다.

   

Ordering of catch processin isn't consist across languages

try~catch 구문에서 C#과 VB.NET의 동작 방법은 다르다.

C#에서는 위에서부터 아래로 넘어갈 수록, 범위가 낮은 exception class로 넘어가게 되지만, VB.NET에서는 exception class로 바로 jump 하게 된다.

static void Main(string[] args)
{
 try
 {
  AMethod();
 }
 catch(Exception ex)
 {
  Console.WriteLine(ex.Message);
 }
 catch(ApplicationException ex)
 {
  Console.WriteLine(ex.Message); <- 절대 수행될 수 없다.
 }
}

   

Type.GetType() might fail at run-time

Type.GetType() 보다는 typeof/GetType를 주로 사용하는 것이 좋다.

   

rethrow isn't consistent

catch(Exception ex)으로 잡힌 error를 throw ex로 해서 다시 던지게 될 경우에는 exception안의 정보를 잃어버릴 수 있다. 이럴때는 catch(Exception)에서 throw로 다시 던져주거나, throw ex.InnerException을 이용해서 Exception을 보내주는 것이 좋다.

   

Versioning may lead to Serialization headaches

: 이미 Serialization된 객체에 대해서 객체의 또다른 member 변수등의 변경이 생겼을 때에, 기존의 serialization의 데이터를 불러오는 데에 문제가 생기게 된다. 이때에, exception을 사용해서 하는 방법도 있으나, 가장 좋은 것은 아래 코드와 같이 Helper를 이용해서 객체의 데이터를 Type의 이름에 따라 얻어오는 방법이다.

  public class SerializationHelper
  {
    /// <summary>
    /// Desirialization이 될때에, 호출을 시켜서 새로 생성되는 객체에 값을 채워주는 함수.
    /// 각각을 enumerator에서 MoveNext로 움직이는 것으로 모든 객체의 값을 얻어온다.
    /// 만약에 구버젼의 Serialization 객체인 경우에는 그 값이 없기 때문에 채워지지 않고,
    /// 기본 값을 얻어오게 된다.
    /// </summary>
    /// <param name="theType"></param>
    /// <param name="instance"></param>
    /// <param name="info"></param>
    public static void SetData(Type theType, Object instance, SerializationInfo info)
    {
      SerializationInfoEnumerator enumerator = info.GetEnumerator();

      while(enumerator.MoveNext())
      {
        string fieldName = enumerator.Current.Name;
        FieldInfo theField =
          theType.GetField(fieldName,
                           BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public |
                           BindingFlags.NonPublic);

        if ( theField != null )
        {
          theField.SetValue(instance, enumerator.Value);
        }
      }
    }

    /// <summary>
    /// Serialization이 될 때에 불러지는 함수
    /// Instance의 모든 값들을 얻어와서 Serialization을 행한다.
    /// </summary>
    /// <param name="theType"></param>
    /// <param name="instance"></param>
    /// <param name="info"></param>
    public static void GetData(Type theType, Object instance, SerializationInfo info)
    {
      FieldInfo[] fields =
        theType.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public |
                          BindingFlags.NonPublic);

      foreach(FieldInfo fieldInfo in fields)
      {
        if(!fieldInfo.IsNotSerialized)
        {
          info.AddValue(fieldInfo.Name, fieldInfo.GetValue(instance));
        }
      }
    }
  }

  

Create Web apps can be painful

blank solution을 만들어 준 후에, 그 안에 project를 만들어주는 것이 project를 만들어주는 것으로 시작하는 것보다 더 낫다.

  • 디자인 된 solution에 원하는 project를 넣는 것이 가능하다. (source의 src, test의 구분이 더 쉬워진다.)
  • 여러 solution에 결합되어 있는 project들의 관리가 보다 용의하다.

IIS에서 virtual directory를 미리 만들어두고, 웹사이트를 만들어주고, 개발을 행하는 것이 훨신더 편한 방법으로 web site의 개발이 가능해진다.

  

Naming XML documentation for IntelliSense support isn't intuitive

XML-style documentation으로 만들어진 code에 대한 xml format은 자동적으로 Visual studio의 intellisense에서 사용되어질 수 잇다. 그렇지만, 하나의 제약으로 가질수 있는 것이, assembly name과 xml file의 이름을 동일하게 해줄 필요가 있다. 자동적으로 찾지는 못한다.

Posted by Y2K
,

The Common Language Runtime(CLR) provides a common platform for the execution of programs in .NET.

.NET language is first translated into the Microsoft Intermediate Language(MSIL).

   

Type alias size doesn't match what you're familiar with

Common Language Specification(CLS)의 특징

  • cross-language integration
  • type safety
  • high-performance execution of managed code

WinAPI의 DllImport 시에 Type 값은 서로간에 byte size를 맞춰줄 필요가 있다.

   

Structure and Class differ in behavior

  • class(reference type) : be created on the heap
  • structure(value type) : be created on the stack

   

Returning value types from a method/property is risky

: Value type으로 return을 받을 경우와 Reference type으로 return을 받을 때, 동작을 유의해야지 된다.

DateTime dtDate = DateTime.Now; <- value type

dtDate.AddDate(1) <- dtDate 값은 변화하지 않음.

   

You can't force calls to your value-type constructors

  • value-type constructor에서 일반 생성자를 호출하는 것은 불가능하다.
  • 값의 초기화를 초기값(int :0, boolean : false) 이외에 값으로 초기화 하는 것이 불가능하다.

   

String concatenation is expensive

  • string에서 string의 모음에서 +를 이용하는 것보다, StringBuilder.Append()를 이용해서 string을 모으는 것이 좋다.
  • 1000000번 '.'를 결합할때, +를 사용하는 경우에는 3562.933 sec가 소요되며, StringBuilder를 사용하는 경우에는 0.07sec의 시간이 소요된다.

   

Exceptions may go unhandled

  • Windows app에서는 Application.ThreadException을 handling 시켜주고, Console app에서는 AppDomain.CurrentDomain.UnhandledException을 handling 시켜줘서 사용해준다.
  • 사용자에게 넘겨주는 모든 error를 사용자에게 넘기지 않고, 내부에서 처리가 되어야지 된다.

   

Uninitialized event handlers aren't treated gracefully

Delegate 된 event의 경우에는 연결되지 않을 경우에는 null reference error가 발생한다.

모든 Event를 동작할 때는 반드시 event의 null point error를 check를 해주는 것이 필요하다.

   

Division operation isn't consistent between types

  • 0로 나뉠때 나오는 에러인 DivisionByZeroException이 나올때, double로 나누어질 때는 eps또는 (+-) 무한대로 나타날 수 있기 때문에, DivisionByZeroException이 나타나지 않을 수 있다.
  • 0로 나뉘어지는 것이 우려될 때는 , IsInfinity() method를 호출해서 값의 형태를 확인해봐야지 된다.

   

Typeless ArrayList isn't type-safe

 System.Collections.ArrayList에서는 모든 데이터가 reference type으로 들어가는 것이 가능하지만, 그 값은 type 변환에 안전하지 못하다.

주의해서 사용하거나, System.Generic을 이용해서 type-safe로 만들어주는 것이 좋다.

  

Type.GetType() may not locate all types

선언되어 있는 class library에서 여러개의 중복된 이름을 가질 수 있기 때문에, 하나의 이름만으로 모든 것을 다 얻어내는 것은 불가능하다. 이때에는 reference type name과 version, public key를 모두 적어줘야지 인식시킬 수 있다.

  

Public key reported by sn.exe is inconsistent

"sn.exe -k"로 key를 만들어줄때는 각 key는 private key만이 갖고 있다. public key는 private key에 pair로 만들어서 서명하는 형식으로 만들어줘야지 된다. Visual Studio 2000에서는 "sn.exe -t" 옵션이 잘못 동작하고 있었다. (구버젼을 사용하는 경우에 주의 할것)

Posted by Y2K
,

Windows Mobile에서는 지원하지 않음. 

재미있어보이는 소스라서 들고오기.  

  

메시지 필터를 이용하여 F1, F2, F3 .. 키 입력을 후킹하기.
public class MessageFilter : System.Windows.Forms.IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        switch(m.Msg)
        {
            case 256 : // WM_KEYDOWN     <==== windows message 를 C# 형태로 쓰고 싶었지만.. 딱히 만들어져있는게 없더군요 그래서
                            //                                    인터넷에서 windows.h 파일을 검색해서 찾았습니다. WM_KETDOWN = 256 번이더군요.
                System.Console.WirteLine(m.LParam.ToInt32());        // 이걸로 F1 부터 여러가지 키를 차례데로 눌러본 값들이
                if( m.LParam.ToInt32() == 3866625 ) // F1 Key            // <===  이 값들입니다. 3866625 가 F1 이군요.. 이런식으로 Key 값을 찾아서
                {                                                                            // 계속 추가하면 키보드 후킹.. 그다지 어려운건 아닐거 같군요 ^^;;
                    System.Console.WriteLine("F1 Press");
                    return true;
                }
                else if( m.LParam.ToInt32() == 3932161 )    // F2 Key
                {
                    System.Console.WriteLine("F2 Press");
                    return true;
                }
                else if( m.LParam.ToInt32() == 3997697 )    // F3 Key
                {
                    System.Console.WriteLine("F3 Press");
                    return true;
                }
                break;
        }
        return false;
    }
}
//
//     만들어 놓은 MessageFilter 는 반드시 AddMessageFilter 메서드를 통해 추가해줘야 합니다.
//    static void Main 함수는 기본 Form 에 포함되어 있습니다.  :) 아시죠?
static void Main()
{
    Application.AddMessageFilter(new MessageFilter());
    Application.Run(new JapExamples());
}
아래 있는 것은 windows.h 파일에 정의된 windos message 들입니다. windows.h 파일은 visual studio 안에 INCLUDE_ROOT 에 있습니다.
어딘지는 아시죠?
WA_ACTIVE 1
WA_CLICKACTIVE 2
WA_INACTIVE 0
WM_ACTIVATE 6
WM_ACTIVATEAPP 28
WM_AFXFIRST 864
WM_AFXLAST 895
WM_APP 32768
WM_ASKCBFORMATNAME 780
WM_CANCELJOURNAL 75
WM_CANCELMODE 31
WM_CAPTURECHANGED 533
WM_CHANGECBCHAIN 781
WM_CHAR 258
WM_CHARTOITEM 47
WM_CHILDACTIVATE 34
WM_CLEAR 771
WM_CLOSE 16
WM_COMMAND 273
WM_COMMNOTIFY 68
WM_COMPACTING 65
WM_COMPAREITEM 57
WM_CONTEXTMENU 123
WM_COPY 769
WM_COPYDATA 74
WM_CREATE 1
WM_CTLCOLORBTN 309
WM_CTLCOLORDLG 310
WM_CTLCOLOREDIT 307
WM_CTLCOLORLISTBOX 308
WM_CTLCOLORMSGBOX 306
WM_CTLCOLORSCROLLBAR 311
WM_CTLCOLORSTATIC 312
WM_CUT 768
WM_DEADCHAR 259
WM_DELETEITEM 45
WM_DESTROY 2
WM_DESTROYCLIPBOARD 775
WM_DEVICECHANGE 537
WM_DEVMODECHANGE 27
WM_DISPLAYCHANGE 126
WM_DRAWCLIPBOARD 776
WM_DRAWITEM 43
WM_DROPFILES 563
WM_ENABLE 10
WM_ENDSESSION 22
WM_ENTERIDLE 289
WM_ENTERMENULOOP 529
WM_ENTERSIZEMOVE 561
WM_ERASEBKGND 20
WM_EXITMENULOOP 530
WM_EXITSIZEMOVE 562
WM_FONTCHANGE 29
WM_GETDLGCODE 135
WM_GETFONT 49
WM_GETHOTKEY 51
WM_GETICON 127
WM_GETMINMAXINFO 36
WM_GETOBJECT 61
WM_GETTEXT 13
WM_GETTEXTLENGTH 14
WM_HANDHELDFIRST 856
WM_HANDHELDLAST 863
WM_HELP 83
WM_HOTKEY 786
WM_HSCROLL 276
WM_HSCROLLCLIPBOARD 782
WM_ICONERASEBKGND 39
WM_IME_CHAR 646
WM_IME_COMPOSITION 271
WM_IME_COMPOSITIONFULL 644
WM_IME_CONTROL 643
WM_IME_ENDCOMPOSITION 270
WM_IME_KEYDOWN 656
WM_IME_KEYLAST 271
WM_IME_KEYUP 657
WM_IME_NOTIFY 642
WM_IME_REQUEST 648
WM_IME_SELECT 645
WM_IME_SETCONTEXT 641
WM_IME_STARTCOMPOSITION 269
WM_INITDIALOG 272
WM_INITMENU 278
WM_INITMENUPOPUP 279
WM_INPUTLANGCHANGE 81
WM_INPUTLANGCHANGEREQUEST 80
WM_KEYDOWN 256
WM_KEYFIRST 256
WM_KEYLAST 264
WM_KEYUP 257
WM_KILLFOCUS 8
WM_LBUTTONDBLCLK 515
WM_LBUTTONDOWN 513
WM_LBUTTONUP 514
WM_MBUTTONDBLCLK 521
WM_MBUTTONDOWN 519
WM_MBUTTONUP 520
WM_MDIACTIVATE 546
WM_MDICASCADE 551
WM_MDICREATE 544
WM_MDIDESTROY 545
WM_MDIGETACTIVE 553
WM_MDIICONARRANGE 552
WM_MDIMAXIMIZE 549
WM_MDINEXT 548
WM_MDIREFRESHMENU 564
WM_MDIRESTORE 547
WM_MDISETMENU 560
WM_MDITILE 550
WM_MEASUREITEM 44
WM_MENUCHAR 288
WM_MENUCOMMAND 294
WM_MENUDRAG 291
WM_MENUGETOBJECT 292
WM_MENURBUTTONUP 290
WM_MENUSELECT 287
WM_MOUSEACTIVATE 33
WM_MOUSEFIRST 512
WM_MOUSEHOVER 673
WM_MOUSELEAVE 675
WM_MOUSEMOVE 512
WM_MOUSEWHEEL 522
WM_MOVE 3
WM_MOVING 534
WM_NCACTIVATE 134
WM_NCCALCSIZE 131
WM_NCCREATE 129
WM_NCDESTROY 130
WM_NCHITTEST 132
WM_NCLBUTTONDBLCLK 163
WM_NCLBUTTONDOWN 161
WM_NCLBUTTONUP 162
WM_NCMBUTTONDBLCLK 169
WM_NCMBUTTONDOWN 167
WM_NCMBUTTONUP 168
WM_NCMOUSEMOVE 160
WM_NCPAINT 133
WM_NCRBUTTONDBLCLK 166
WM_NCRBUTTONDOWN 164
WM_NCRBUTTONUP 165
WM_NEXTDLGCTL 40
WM_NEXTMENU 531
WM_NOTIFY 78
WM_NOTIFYFORMAT 85
WM_NULL 0
WM_PAINT 15
WM_PAINTCLIPBOARD 777
WM_PAINTICON 38
WM_PALETTECHANGED 785
WM_PALETTEISCHANGING 784
WM_PARENTNOTIFY 528
WM_PASTE 770
WM_PENWINFIRST 896
WM_PENWINLAST 911
WM_POWER 72
WM_POWERBROADCAST 536
WM_PRINT 791
WM_PRINTCLIENT 792
WM_QUERYDRAGICON 55
WM_QUERYENDSESSION 17
WM_QUERYNEWPALETTE 783
WM_QUERYOPEN 19
WM_QUEUESYNC 35
WM_QUIT 18
WM_RBUTTONDBLCLK 518
WM_RBUTTONDOWN 516
WM_RBUTTONUP 517
WM_RENDERALLFORMATS 774
WM_RENDERFORMAT 773
WM_SETCURSOR 32
WM_SETFOCUS 7
WM_SETFONT 48
WM_SETHOTKEY 50
WM_SETICON 128
WM_SETREDRAW 11
WM_SETTEXT 12
WM_SETTINGCHANGE 26
WM_SHOWWINDOW 24
WM_SIZE 5
WM_SIZECLIPBOARD 779
WM_SIZING 532
WM_SPOOLERSTATUS 42
WM_STYLECHANGED 125
WM_STYLECHANGING 124
WM_SYNCPAINT 136
WM_SYSCHAR 262
WM_SYSCOLORCHANGE 21
WM_SYSCOMMAND 274
WM_SYSDEADCHAR 263
WM_SYSKEYDOWN 260
WM_SYSKEYUP 261
WM_TCARD 82
WM_TIMECHANGE 30
WM_TIMER 275
WM_UNDO 772
WM_UNINITMENUPOPUP 293
WM_USER 1024
WM_USERCHANGED 84
WM_VKEYTOITEM 46
WM_VSCROLL 277
WM_VSCROLLCLIPBOARD 778
WM_WINDOWPOSCHANGED 71
WM_WINDOWPOSCHANGING 70
WM_WININICHANGE 26

출처 : 데브피아(http://www.devpia.com/forum/BoardView.aspx?no=46886&page=2&Tpage=1501&forumname=csharp_qa&stype=&ctType=&answer=) 

Posted by Y2K
,