Software Development/C#

.Net Framework Guideline - Naming Rule(.net 프레임워크 디자인 지침 - 명명 지침) 정리

huiyu 2021. 8. 25. 11:39

대/소문자 표기법

식별자용 대/소문자 규칙

 식별자 내 단어를 구분하기 위해서 식별자 각 단어의 첫 글자는 대문자를 사용, 밑줄을 사용하여 단어를 구분하지 않는다.

 - PascalCasing : 파스칼 표기법
 - camelCasing : 카멜 표기법

1) 매개 변수 이름을 제외한 모든 식별자에 사용하는 파스칼 표기법은 아래와 같이 각 단어의 첫 번째 글자를 대문자로 표기

    - PropertyDescriptor, HtmlTag

  아래와 같이 두 글자 머리글자어(two-letter acronyms)를 모두 대문자로 표기하기도 함.

    - IOStream

2) 매개 변수 이름에만 사용하는 카멜 표기법은 아래 예제와 같이 첫 단어를 제외한 각 단어의 첫 번째 글자를 대문자로 표기, 두 글자 머리글자어(two-letter acronyms)는 모두 소문자로 표기

   - propertyDescriptor, ioStream, htmlTag

* 모든 공개 멤버(public member), 형식(type) 및 여러 단어로 구성된 네임스페이스(namespace)는 모두 PascalCasing을 사용
* 매개 변수 이름은 camelCasing을 사용

- 다양한 유형의 식별자에 대한 대/소문자 규칙

ID 대/소문자 구분 예제
네임스페이스(Namespace) Pascal namespace System.Security {...}
형식(Type) Pascal namespace class StreamReader {...}
인터페이스(Interface) Pascal namespace interface IEnumerable {...}
메서드(Method) Pascal public class Object{
  public virtual string ToString();
}
속성(Property) Pascal public class String{
  public int Length { get; }
}
이벤트(Event) Pascal public class Process {
  public event EventHandler Exited;
}
필드(Field) Pascal public class MessageQueue{
  public static readonly TimeSpan InfiniteTimeout;
}
public struct UInt32 {
  public const Min = 0;
}
열거형 값(Enum value) Pascal public enum FileMode {
  Append,
  ...
}
매개 변수(Parameter) Camel public class Convert {
  public static int ToInt32(string value);
}

 

복합어(Compound Words) 와 일반 용어(Common Terms) 대/소문자 표기

 대부분의 복합어는 대/소문자 표기 시 단일 단어로 취급, 닫힌 형식의 복합어(closed-form compound word)는 각 단어를 대문자로 표기하지 않는다.
  *
 영어의 복합어
   - Closed-form(닫힌 복합어) : 두 단어가 마치 하나인 것처럼 묶어서 쓰이는 경우(ex:endpoint)
   - Hyphenated-form : 두 단어를 하이픈으로 연결하는 경우(ex:single-minded)
   - Open-form(열린 복합어) : 공백을 중간에 두는 경우(ex:disatance learning)

Pascal Camel Not
BitFlag bitFlag Bitflag
Callback callback CallBack
Canceled canceled Cancelled
DoNot doNot Don't
Email email EMail
Endpoint endpoint EndPoint
FileName fileName Filename
Gridline gridline GridLine
Hashtable hashtable HashTable
Id id ID
Indexes indexes Indices
LogOff logOff LogOut
LogOn logOn LogIn
Metadata metadata MetaData, metaData
Multipanel multipanel MultiPanel
Multiview multiview MultiView
Namespace namespace NameSpace
Ok ok OK
Pi pi PI
Placeholder placeholder PlaceHolder
SignIn signIn SignOn
SignOut signOut SignOff
UserName userName Username
WhiteSpace whiteSpace Whitespace
Writable writable Writeable

 

대/소문자 구분

* 모든 프로그래밍 언어가 대/소문자를 구분한다고 가정하지 않는다. 대/소문자만 다른 이름을 지정해선 안된다.

 

일반 명명 규칙

단어 선택

 - 쉽게 읽을 수 있는 식별자 이름을 선택할 것, 예를 들면 'HorizontalAlignment'라는 이름은 'AlignmentHorizontal'보다 영어로 읽기 쉽다.
 - 간결함보단 가독성을 우선할 것, 속성 이름 'CanScrollHorizontally'는 X축에 대한 모호한 참조인 'ScrollableX'보다 좋은 이름이다.

 - 영숫자(라틴문자+아라비아 숫자)가 아닌 밑줄(_)이나 하이픈(-)을 사용하지 말 것.
 - 헝가리식 표기법을 사용하지 말 것.
  * 헝기리식/헝가리안 표기법(Hungraian Notation) : 컴퓨터 프로그래밍에서 변수 및 함수 이름 인자 앞에 데이터 타입을 명시하는 코드 규칙, 예전에는 IDE가 부실했기 때문에 유용했으나 요즘엔 IDE를 통해 데이터 타입이 쉽게 확인이 가능하기 때문에 구식 표기법, MS에서도 사용하지 않을 것을 권고.

- 널리 사용되는 프로그래밍 언어의 키워드(keyword)와 충돌하는 식별자는 사용하지 말 것.

약어 및 머리글자어 사용

 - 약어나 축약어를 식별자 이름의 일부로 사용하지 말 것. 예를 들면 'GetWin' 대신 'GetWindow'를 사용할 것.
 - 일반적으로 받아들여지지 않는 머리글자어는 사용하지 말고, 받아들여지는 머리글자어라도 필요할 경우에만 사용할 것.

특정 언어에 국한되는 이름 사용 금지

 - 형식 이름에는 특정 언어에 국한되는 키워드 대신 의미를 담은 이름을 사용할 것, GetInt보다는 GetLength가 더 좋은 이름.
 - 식별자에 형식 이상의 의미가 없다면 특정 언어에 국한되는 이름 대신 일반적인 CLR 형식 이름을 사용할 것.
  예를 들어 Int64로 변환하는 메서드 이름은 ToLong이 아닌 ToInt64로 지정해야 한다. Int64는 C# 전용 별칭인 long의 CLR 이름이기 때문이다. (CLR : Common Language Runtime, 공용 언어 런타임)

C# Visual Basic C++ CLR
sbyte SByte char SByte
바이트 Byte unsigned char Byte
short Short short Int16
ushort UInt16 unsigned short UInt16
int Integer int Int32
uint UInt32 unsigned int UInt32
long Long __int64 Int64
ulong UInt64 unsigned __int64 UInt64
float Single float Single
double double double double
bool Boolean bool Boolean
char Char wchar_t Char
string String String String
object Object Object Object

- 식별자에 의미가 없고 매개변수 유형이 중요하지 않는 경우엔 type(유형) 이름을 반복하지 않고, 'value'나 'item' 같은 일반적인 이름(common name)을 사용할 것

기존 API의 새로운 버전의 이름 지정(Naming New Versions of Exsiting APIs)

 - 기존 API의 새 버전을 만들 때는 기존 API와 유사한 이름을 사용하여 API간의 관계를 쉽게 강조한다.
 - 접두사 대신 접미사를 추가하여 기존 API의 새 버전을 표시한다. 이렇게 할 경우 IntelliSense를 사용하여 보다 쉽게 찾을 수 있다.
 - 접미사나 접두사를 추가하는 것보단 의미있는 새 식별자를 사용할 것
 - 숫자 접미사를 사용해 기존 API의 새 버전을 표시. API의 기존 이름이 의미가 통하는 유일한 이름이며(업계 표준), 의미 있는 접미사 추가(또는 이름 변경)이 어려울 경우 이 방법을 사용
 - 동일한 API의 이전 버전과 구분하기 위해 식별자에 'Ex'(또는 이와 유사한) 접미사를 사용하지 말 것.
 - 32비트 정수 대신 64비트 정수(long 정수)에서 작동하는 API 버전을 도입할 때는 '64' 접미사를 사용할 것. 이 방법은 기존 32비트 API가 있을 경우만 사용할 것. 64비트 버전만 있는 새 API에는 사용하지 말 것.

 

어셈블리 및 DLL 이름

 어셈블리는 관리 코드 프로그램에 대한 배포 단위. 어셈블리 및 DLL 이름은 네임 스페이스와 일치하지 않아도 되지만, 어셈블리 이름을 지정할 때 네임 스페이스 이름을 따르는 것이 적절하다.
 좋은 방법은 어셈블리에 포함된 네임스페이스의 공통 접두사를 기반으로 DLL 이름을 설정하는 것. 예를들어 1)'MyCompany.MyTechonlogy.FirstFeature'와 2)MyCompany.MyTechonlogy.SecondFeature는 공통된 'MyCompany.MyTechonlogy.dll'로 설정할 수 있다.
 또한 'System.Data' 와 같이 많은 기능을 담는 어셈블리 dll 이름을 선택한다.

일반적으로 다음 패턴에 따라 dll의 이름을 지정하는 것이 좋다.

<Company>.<Components>.dll

-> ex : Litware.Controls.dll

 

네임스페이스의 이름

 다른 명명 지침과 마찬가지로 네임 스페이스의 이름을 지정할 때 개발자에게 네임스페이스 이름만 보고도 콘텐츠를 즉시 알 수 있는 명확성을 주는 것이 중요. 다음은 네임스페이스 지정의 일반적인 규칙

<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]

-> ex : 'Febrikm.Math' , 'Litware.Security'

- 여러 회사의 네임스페이스가 같은 이름을 갖지 않도록 네임 스페이스 이름에 회사 이름을 접두사로 사용
- 네임 스페이스 이름의 두번째 수준에서 안정적인 버전의 독립 제품 이름을 사용
- 회사 내의 그룹 이름은 수명이 짧기 때문에 네임 스페이스 이름으로 사용하지 말 것.
- PascalCase로 대/소문자 구분을 사용하고, 네임 스페이스 구성 요소는 마침표로 구분(ex:Microsoft.Office.PowerPowerPoint). 특수한 대/소문자 구문을 사용하는 경우라면 브랜드에서 정의한 대/소문자 구분을 따른다.
- 복수형 네임 스페이스가 필요한 경우 복수형을 사용한다.
  ex: System.Collection -> System.Collections, 브랜드 이름이나 머리글자어의 경우 예외. System.IOs가 아닌 System.IO를 사용.

- 네임스페이스와 동일한 이름의 type(형식)을 제공하지 않는다.
  ex:  'Debug' 네임스페이스와 동일한 'Debug' 클래스 제공

네임 스페이스 및 형식 이름 충돌

 generic type name(제네릭 형식 이름)을 사용하지 않는다(Element, Node, Log, Message..)
 일반적인 경우 충돌(Conflict)할 확률이 높다. 제네릭 형식 이름을 한정하여 사용한다 -> FormElement, XmlNode, EventLog

 네임스페이스의 다양한 범주에 대하여 충돌을 방지하기 위한 방법

  - 응용 프로그램 모델 네임 스페이스(Application model namespaces)
    단일 응용 프로그램 모델(Single Application model)에 속한 네임 스페이스는 함께 사용되는 경우가 많지만, 다른 응용 프로그램 모델의 네임 스페이스와는 거의 사용되지 않는다. 예를들어 System.Window.Forms는 System.Web.UI와 함께 사용되지 않는다.
  -> 잘 알려진 Application Model Namspace : System.Window*, System.Web.UI*
  -> 단일 응용 프로그램 모델 내에서 네임 스페이스 형식에 동일한 이름을 지정하지 말 것. 예를 들어 System.Web.UI는 'Page' type이 이미 존재하고 있으므로 System.Web.UI.Adapters엔 동일한 이름을 갖는 'Page'를 추가하지 말 것.

- 인프라 네임 스페이스(Infrastructure namespaces)
  일반적인 응용 프로그램을 개발하는 동안 거의 가져오지 않는 네임 스페이스, 예를들어 '.Design' 네임 스페이스가 있으며, 이는 프로그래밍 도구를 개발할 때 사용한다. 이러한 충돌 방지는 critical하지 않음.

- 핵심 네임 스페이스(Core namespace)
  모든 'System' namespace를 포함한다. (Application models namespace & Infastructure namspace 제외)
  -> System, System.IO, System.Xml, System.Net

  * 핵심 네임 스페이스와 충돌하는 type(형식) 이름은 사용하지 말 것. 예를들어  'Stream'은 System.IO.Stream과 충돌

- 기술 네임 스페이스(Technology namespace groups)
  이 범주에선 처음 두 네임 스페이스 노드를 포함하는 모든 네임스페이스의 경우.<Company>.<Technology>*
  예를들어, Microsoft.Build.Utilities 와 Microsoft.Build.Taks. <-- 단일 기술에 속한 형식이 서로 충돌하지 않게 할 것!

  * 단일 기술에서 다른 형식(type)과 충돌하는 형식(type) 이름을 할당하지 말 것.
  * technology namespace와 application model namespace 사이에 충돌(conflict)을 일으키지 말 것
   (technology namespace 모델과 application model이 함께 사용할 수 없는 경우 제외)

 

클래스, 구조체 및 인터페이스 이름

 - 클래스와 구조체의 이름은 명사(nouns)와 명사구(noun phrases)를 사용(using PascalCase)
   동사구(verb phrases)로 이름 지어지는 메서드(method)와 구분

  - 인터페이스의 이름은 형용사 구(adjective phrases)를 사용, 때때로 명사나 명사구를 사용하는 경우도 있다.
   (명사와 명사구는 거의 사용되지 않으며 형식이 인터페이스가 아닌 추상클래스(abstract class)일 경우 사용)

  - 클래스 이름을 접두사로 지정하지 말것(ex:"C")

  - 상속받은 클래스의 이름은 base 클래스의 이름을 뒤에 둘 것을 고려.
   이는 읽기 쉬우며, 코드간의 관계를 명확하게 알 수 있다.
   (ex : Exception을 상속받은 ArgumentOutOfRangeException, Attribute를 상속받은 SerializableAttribute)
   * 이 가이드를 적용시엔 적절한 판단이 필요하다. (ex : Button 클래스는 Control을 상속받았으나, 이름에 명시하지 않음)

 - 인터페이스 앞에 접두사(prefix) 문자 'I'를 붙여 인터페이스임을 나타낸다. 다른 형식과 마찬가지로 약어를 사용하지 않는다.
  예를들어 IComponent(명사), ICustomAttributeProvider(명사구), IPersistable(형용사)

  - DO ensure that the names differ only by the "I" prefix on the interface name when you are defining a class–interface pair where the class is a standard implementation of the interface.
 (??)

제네릭 형식 매개 변수의 이름(Names of Generic Type Parameters)

 - 단일 문자(single-letter) 이름이 설명이 없는 경우 설명이 포함된 제네릭 형식 매개변수 이름 지정.
 - 하나의 단일 문자(single-letter) 매개변수(parameter) 의 경우 'T'를 사용(???)

public int IComparer<T> { ... }
public delegate bool Predicate<T>(T item);
public struct Nullable<T> where T:struct { ... }

 -  DO prefix descriptive type parameter names with T.

public interface ISessionChannel<TSession> where TSession : ISession {
    TSession Session { get; }
}

- 매개 변수 이름(name of the parameter)에서 형식 매개변수(type parameter)에 적용되는 제약 조건을 표시

public interface ISessionChannel<TSession> where TSession : ISession {
    TSession Session { get; }
}

For example, a parameter constrained to ISession might be called TSession.

** 제네릭은 좀더 봐야할듯..

공용 형식의 이름

 특정 형식을 구현(implementing)하거나 상속(derived)받을 경우 아래 지침을 따른다.

Base Type Derived/Implementing Type Guideline
System.Attribute - 사용자 지정 특성 클래스(Custom attribute class)의 이름에 접미사 'Attribute' 추가
System.Delegate - 이벤트에 사용되는 대리자(delegate) 이름에 'EventHandler' 접미사 추가
- 이벤트 처리기로 사용된 대리자 이외의 이름에 'Callback' 접미사 추가
- 대리자(delegate)에 'Delegate' 접미사는 추가하지 말 것
System.EventArgs - EventArgs 접미사 추가
System.Enum - Enum 클래스는 상속받지 않는다. 대신 'eum' 키워드를 사용
- 'Enum' 이나 'Flag' 접미사는 사용하지 않는다.
System.Exception - 접미사 Exception 추가
IDictionary
IDictionary<TKey,TValue>
- 접미사 'Dictionary'를 추가, 'IDictionary'는 특정 유형의 컬렉션이지만 일반적인 컬렉션 지침보다 우선 적용
IEnumerable
ICollection
IList
IEnumerable<T>
ICollection<T>
IList<T>
- 'Collection' 접미사 추가
System.IO.Stream - 'Stream' 접미사 추가
IPermission - 'Permission' 접미사 추가

 

열거형 이름 지정 (Naming Enumerations)

 일반적으로 표준 형식 명명 규칙을 따른다(PascalCasing, etc). 그러나 적용되는 추가 가이드가 있다.

- 비트 필드의 경우를 제외하고는 단수 형식 이름을 사용
- 비트필드를 사용하는 경우에는 복수형 형식 이름을 사용
- 열거형 형식 이름에 'Enum' 접미사를 사용하지 말 것.
- 열거형 형식 이름에는 'Flag' 또는 'Flags' 접미사를 사용하지 말 것
- 열거형 값 이름에 접두사를 사용하지 말 것(ex : ADO 열거형의 경우 'ad'를 앞에 붙이지 말것, 서식있는 텍스트 열거형의 경우 'rtf'를 붙이지 말 것)

 

형식 멤버의 이름(Names of Type Members)

 형식(Types)은 메서드(Methods), 속성(Properties), 이벤트(Events), 생성자(Constructors), 필드(Fields)의 멤버로 구성

메서드 이름(Names of Methods)

 작업을 수행하는 동작이기 때문에 디자인 가이드라인에서는 메서드 이름을 동사나 동사구로 지정하도록 함. 이 가이드라인에 따르면 명사나 형용사구로 정의한 속성(Properties)과 형식(Types) 이름을 구분할 수 있다.

- 메서드의 이름은 동사 또는 동사구를 사용

public class String {
    public int CompareTo(...);
    public string[] Split(...);
    public string Trim();
}

속성 이름(Names of Properties)

 속성은 명사나 형용사로 지정, 속성은 데이터를 나타내고 이를 반영해야 한다. PascalCasing 사용.

 - 명사, 명사구 또는 형용사를 사용하여 속성 이름 지정
 - 다음 예제와 같이 'Get' 메서드 이름과 일치하는 속성은 갖지 않는다. 일반적으로 Get 속성이 실제로 메서드.

public string TextWriter { get {...} set {...} } 
public string GetTextWriter(int value) { ... }

 - Collection 속성(Properties)은 'List'나 'Collection' 같은 단일 구를 사용하지 않고, 컬렉션을 설명하는 복수 구를 이름으로 사용한다.
 - boolean 속성(Properties)은 긍정적인 문구(affirmative phrase)를 사용한다.(CantSeek이 아닌 CanSeek). 접두사로 'Is','Can' 또는 'Has' 등을 추가 할 수 있다.

 - 속성에 해당 형식(Type)과 같은 이름을 지정하는 것이 좋다. 예를 들어 아래 코드는 올바르게 enum Color값을 set/get하고 사용할 수 있으므로, 속성 이름은 'Color'로 사용한다.

public enum Color {...}
public class Control {
    public Color Color { get {...} set {...} }
}

이벤트 이름

 이벤트는 발생 중인 작업이나 발생한 작업을 가리킨다. 메서드와 마찬가지로 동사를 사용하여 명명하고, 시제는 이벤트가 발생할 시간을 나타낸다.

- 동사 또는 동사구를 사용하여 이벤트 이름 지정 (Clicked, Painting, DroppedDown ...)
- 현재 및 과거 시제를 사용하여 이벤트 발생 전/후 이벤트 이름 제공
  예를들어 창이 닫히기 전에 발생하는 닫기 이벤트는 'Closing', 창이 닫힌 우 발생하는 이벤트는 'Closed'라고 제공

- 'Before', 'After'와 같은 접두사로 사전/사후 이벤트를 나타내지 말 것, 위의 설명대로 과거 및 현재 시제를 사용
- 이벤트 처리기에는 'EventHandler'접미사를 사용.

public delegate void ClickedEventHandler(object sender, ClickedEventArgs e);

- 이벤트 처리기에는 sender와 e 두개의 매개변수를 사용, sender는 이벤트를 발생시킨 개체이며 구체적으로 형식을 적용할 수 있더라도 'object'형식을 사용한다.
- 이벤트 인수 클래스에는 'EventArgs' 접미사를 붙여 사용.

필드 이름

필드 명명 규칙은 공용 및 보호된 고정 필드(static public and protected fields)에 적용.
내부 및 개인 필드 (Internal and private fields)는 적용되지 않는다.(이는 멤버 디자인 지침에 명시)

- 필드 이름에는 PascalCasing을 사용
- 명사, 명사구 또는 형용사를 사용하여 이름 지정.
- 필드 이름에는 접두사를 사용하지 않는다. 예를 들어 'g_' 또는 's_'를 사용하여 고정 필드를 나타내지 않는다.

 

매개 변수 이름 지정(Naming Parameters)

 개발도구나 Intellisense에서 매개 변수에 대한 설명과 정보가 표기되기 때문에 가독성을 명확하게 하여 제공 필요.

- 매개변수의 경우엔 camelCasing 사용.
- 설명이 포함된 매개 변수 이름을 사용(✔️ DO use descriptive parameter names.)
- 매개변수의 형식이 아닌 매개변수의 의미에 따라 이름을 정의

명명 연산자 오버로드 매개 변수(Naming Operator Overload Parameters)

- 의미가 없는 이항 연산자 오버로드의 경우 매개변수의 이름을 'left'와 'right'로 사용.
- 의미가 없는 단항 연산자 오버로드의 경우 매개변수의 이름을 'value'로 사용
- 연산자 오버로드 매개변수의 경우 의미있는 이름을 고려하여, 중요한 값을 추가한다.
- 오버로드 매개변수 이름에 약어나 숫자 인덱스는 사용하지 않는다.

 

리소스 지정 이름

 지역화할 수 있는 리소스(Localizable resources)는 속성과 같이 특정 개체를 통해 참조될 수 있기 때문에 속성 지침과 비슷하다.

 - PascalCase 사용
 - 짧은 약어를 사용하는 것보단 설명이 포함된 이름을 사용한다.
 - CLR 언어의 키워드를 사용하지 않는다.
 - 리소스 이름 지정에는 영숫자(alphanumeric characters)와 밑줄(underscores)만 사용한다.
 - 리소스 식별자는 예외 형식 이름(exception type name) 및 예외의 짧은 식별자(short identifier of the exception)를 사용해야 한다.
   ex : ArgumentExceptionIllegalCharacters, ArgumentExceptionInvalidName, ArgumentExceptionFileNameIsMalformed

 

 

참고 : https://docs.microsoft.com/ko-kr/dotnet/standard/design-guidelines/naming-guidelines

 

명명 지침 - Framework Design Guidelines

이 개요에서는 프레임 워크 개발에 사용할 명명 규칙을 참조 하세요. 대문자 표시, 일반 이름 지정 및 기타 지침을 다루는 문서로 이동 합니다.

docs.microsoft.com

 

728x90