_var클래스 필드에서 변수 이름 을 보는 것이 일반적 입니다. 밑줄은 무엇을 의미합니까? 이러한 모든 특수 명명 규칙에 대한 참조가 있습니까?
_var클래스 필드에서 변수 이름 을 보는 것이 일반적 입니다. 밑줄은 무엇을 의미합니까? 이러한 모든 특수 명명 규칙에 대한 참조가 있습니까?
답변:
밑줄은 단순히 규칙입니다. 더 이상 없습니다. 따라서 그 사용은 항상 사람마다 다소 다릅니다. 문제의 두 언어에 대해 이해하는 방법은 다음과 같습니다.
C ++에서 밑줄은 일반적으로 개인 멤버 변수를 나타냅니다.
C #에서는 일반적으로 공용 속성에 기본 개인 멤버 변수를 정의 할 때만 사용됩니다. 다른 개인 멤버 변수에는 밑줄이 없습니다. 이 사용법은 자동 속성의 출현으로 대체로 길을 갔다.
전에:
private string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}
후:
public string Name { get; set; }
public string Name { get; private set; }. 사실, 그것은 불변의 것이 아니지만 거기에 있습니다.
_var예약되지 않았습니다.
C ++에서 변수 이름 또는 매개 변수 이름 앞에 UNDERSCORES를 사용하지 않는 것이 좋습니다.
밑줄 또는 이중 밑줄로 시작하는 이름은 C ++ 구현자를 위해 예약됩니다. 밑줄이있는 이름은 라이브러리가 작동하도록 예약되어 있습니다.
C ++ 코딩 표준을 읽으면 첫 페이지에 다음과 같이 표시됩니다.
"명명을 과대 평가하지 말고 일관된 명명 규칙을 사용하십시오. 두 가지 필수 사항 만 있습니다. (p2, C ++ 코딩 표준, 허브 셔터 및 Andrei Alexandrescu)
보다 구체적으로, ISO 실무 초안 에는 실제 규칙이 나와 있습니다.
또한 일부 식별자는 C ++ 구현에서 사용하도록 예약되어 있으며 다른 방식으로 사용해서는 안됩니다. 진단이 필요하지 않습니다. (a) 이중 밑줄 __을 포함하거나 밑줄로 시작하고 대문자로 시작하는 각 식별자는 모든 사용을 위해 구현에 예약되어 있습니다. (b) 밑줄로 시작하는 각 식별자는 전역 네임 스페이스에서 이름으로 사용하기 위해 구현에 예약되어 있습니다.
실수로 위의 제한 중 하나에 빠질 경우 밑줄로 기호를 시작하지 않는 것이 가장 좋습니다.
소프트웨어를 개발할 때 이러한 밑줄을 사용하는 것이 왜 비참한 지 스스로 알 수 있습니다.
다음과 같이 간단한 helloWorld.cpp 프로그램을 컴파일하십시오.
g++ -E helloWorld.cpp
백그라운드에서 발생하는 모든 것을 볼 수 있습니다. 다음은 스 니펫입니다.
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
__streambuf_type* __sb = this->rdbuf();
if (__sb)
{
if (__sb->pubsync() == -1)
__err |= ios_base::badbit;
else
__ret = 0;
}
이중 밑줄로 시작하는 이름의 수를 볼 수 있습니다!
또한 가상 멤버 함수를 보면 * _vptr은 클래스에서 하나 이상의 가상 멤버 함수를 사용할 때 자동으로 생성되는 가상 테이블에 대해 생성 된 포인터임을 알 수 있습니다! 그러나 그것은 또 다른 이야기입니다 ...
밑줄을 사용하면 충돌 문제가 발생할 수 있으며 너무 늦을 때까지 그 원인을 파악할 수 없습니다.
실제로이 _var규칙은 C #이나 C ++가 아닌 VB에서 나옵니다 (m _, ...는 또 다른 것입니다).
이는 속성을 선언 할 때 VB의 대 / 소문자 구분을 극복했습니다.
예를 들어, 이러한 코드는 고려되기 때문 VB에서 불가능 user와 User동일한 식별자
Private user As String
Public Property User As String
Get
Return user
End Get
Set(ByVal Value As String)
user = value
End Set
End Property
이를 극복하기 위해 일부 사람들은 '_'을 개인 필드에 추가하여 다음과 같이 표시했습니다.
Private _user As String
Public Property User As String
Get
Return _user
End Get
Set(ByVal Value As String)
_user = value
End Set
End Property
많은 규칙이 .Net에 대한 것이며 C #과 VB.NET 규칙간에 균일 성을 유지하기 위해 동일한 규칙을 사용하고 있습니다.
내가 말한 것에 대한 참조를 찾았습니다 : http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
밑줄이있는 낙타 케이스. VB.NET에서 항상 "Protected"또는 "Private"를 표시하고 "Dim"을 사용하지 마십시오. "m_"의 사용은 권장되지 않는 보호 된 변수의 경우에만 속성과 다른 경우에만 속성과 다른 변수 이름을 사용하지 않는 것이 좋습니다. VB.NET에서 프로그램을 프로그래밍 할 때 삶을 고통스럽게 할 수 있습니다. 접근 자 / 돌연변이 속성과 다른 이름을 멤버에 지정해야합니다. 여기에있는 모든 항목 중 주요 밑줄은 실제로 유일한 논란입니다. 개인적으로 변수에 밑줄이없는 낙타보다 선호하기 때문에 변수 이름을 "this"로 한정 할 필요가 없습니다. 이름 충돌이 발생할 가능성이있는 생성자 또는 다른 곳의 매개 변수와 구별하기 위해. VB.NET의 대소 문자를 구분하지 않으면 접근 자 속성의 이름이 밑줄을 제외하고 개인 멤버 변수와 같은 이름을 가지므로 더욱 중요합니다. m_가가는 한, 그것은 실제로 미학에 관한 것입니다. 변수 이름에 구멍이있는 것처럼 보이기 때문에 나 (그리고 다른 많은 사람들)는 m_ ugly를 찾습니다. 거의 모욕적입니다. 나는 항상 VB6에서 그것을 사용했지만 변수는 선행 밑줄을 가질 수 없었기 때문입니다. 나는 그것이 사라지는 것을보고 더 행복 할 수 없었다. 코드에서 두 가지를 모두 수행했지만 m_ (및 직선 _)을 사용하지 않는 것이 좋습니다. 또한, "m"으로 시작하는 접두사도 있습니다. 물론 이들은 주로 C #으로 코딩되므로 속성과 경우에만 다른 개인 멤버를 가질 수 있습니다. VB 사람들은 다른 일을해야합니다. 언어 별 특수한 경우를 시도하기보다는이를 지원할 모든 언어에 대해 밑줄을 사용하는 것이 좋습니다. 클래스가 CLS를 완전히 준수하도록하려면 C # 보호 멤버 변수의 접두사를 생략 할 수 있습니다. 그러나 실제로 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 지원할 모든 언어에 대해 밑줄을 사용하는 것이 좋습니다. 클래스가 CLS를 완전히 준수하도록하려면 C # 보호 멤버 변수의 접두사를 생략 할 수 있습니다. 그러나 실제로 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 지원할 모든 언어에 대해 밑줄을 사용하는 것이 좋습니다. 클래스가 CLS를 완전히 준수하도록하려면 C # 보호 멤버 변수의 접두사를 생략 할 수 있습니다. 그러나 실제로 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. .
첫 번째 주석 자 (R Samuel Klatchko) 는 다음과 같이 언급했습니다. C ++ 식별자에 밑줄을 사용하는 것에 대한 규칙은 무엇입니까? C ++의 밑줄에 대한 질문에 대답합니다. 일반적으로 컴파일러의 구현자를 위해 예약되어 있으므로 밑줄을 사용하지 않아야합니다. 당신이보고있는 코드 _var는 아마도 레거시 코드이거나 오래된 밑줄을 찌르지 않는 오래된 명명 시스템을 사용하여 자란 누군가가 작성한 코드 일 것입니다.
다른 답변 상태로, 클래스 멤버 변수를 식별하기 위해 C ++에서 사용되었습니다. 그러나 데코레이터 나 구문이 사용되는 한 특별한 의미는 없습니다. 그래서 당신이 그것을 사용하려면 컴파일됩니다.
C # 토론을 다른 사람에게 맡기겠습니다.
고유 한 코딩 지침을 만들 수 있습니다. 나머지 팀을 위해 명확한 문서를 작성하십시오.
_field를 사용하면 Intelilsense에서 _ 만 입력하면 모든 클래스 변수를 필터링 할 수 있습니다.
나는 보통 Brad Adams Guidelines 를 따르지만 밑줄을 사용하지 않는 것이 좋습니다.
C #에서 Microsoft Framework Design Guidelines 는 공용 멤버에 밑줄 문자를 사용하지 않는 것이 좋습니다 . 내용은 개인 회원, 밑줄은 사용하기 OK입니다. 실제로 Jeffrey Richter (가이드 라인에 종종 언급 됨)는 m_를 사용하고 개인 정적 멤버는 "s_"를 사용합니다.
개인적으로 저는 _를 사용하여 개인 회원을 표시합니다. "m_"및 "s_"는 헝가리어 표기법에 따라 .NET에서 찌그러 질뿐만 아니라 매우 장황 할 수 있으며 많은 구성원이있는 클래스를 알파벳순으로 빠른 시선 검사를하기가 어렵습니다 (모두 10 개의 변수가 m_로 시작한다고 상상해보십시오) .
클래스의 멤버 변수에 _var 이름을 사용합니다. 내가하는 두 가지 주요 이유가 있습니다.
1) 나중에 코드를 읽을 때 클래스 변수와 로컬 함수 변수를 추적하는 데 도움이됩니다.
2) 클래스 변수를 찾을 때 Intellisense (또는 다른 코드 완성 시스템)에서 도움이됩니다. 첫 번째 문자 만 아는 것이 사용 가능한 변수 및 메소드 목록을 필터링하는 데 도움이됩니다.
C 및 C ++ 언어와 관련하여 이름의 밑줄 (시작, 중간 또는 끝)에는 특별한 의미가 없습니다. 유효한 변수 이름 문자 일뿐입니다. "컨벤션"은 코딩 커뮤니티 내의 코딩 관행에서 비롯됩니다.
위에서 다양한 예에서 이미 언급했듯이 처음에 _은 C ++에서 클래스의 개인 또는 보호 멤버를 의미 할 수 있습니다.
재미있는 사소한 역사를 알려 드리겠습니다. UNIX에서 코어 C 라이브러리 함수와 커널 함수를 사용자 공간에 노출하려는 커널 백엔드가있는 경우 _는 다른 작업을 수행하지 않고 커널 함수를 직접 호출하는 함수 스텁 앞에 붙어 있습니다. 가장 유명하고 친숙한 예는 BSD 및 SysV 유형 커널에서 exit () vs _exit ()입니다. 여기서 exit ()는 커널의 종료 서비스를 호출하기 전에 사용자 공간 작업을 수행하지만 _exit은 커널의 종료 서비스에 매핑됩니다.
따라서 _는 "로컬"항목에 사용되었으며이 경우 로컬은 로컬 머신입니다. 일반적으로 _functions ()는 이식성이 없었습니다. 다양한 플랫폼에서 동일한 동작을 기 대해서는 안됩니다.
이제 변수 이름에서 _와 같은
int _foo;
심리적으로, _는 처음에 입력해야하는 이상한 일입니다. 따라서 다른 프로세서와 충돌 할 가능성이 적은 변수 이름을 만들려는 경우, 특히 전 처리기 대체를 처리 할 때 _의 사용을 고려하십시오.
저의 기본 조언은 코딩 커뮤니티의 컨벤션을 항상 준수하여보다 효과적으로 협업 할 수 있도록하는 것입니다.
VB.NET에서 코드를 확장 할 수 있어야하는 경우 C # 에서 코드 를 사용해야하는 합법적 인 이유가 있습니다 . (그렇지 않으면 안됩니다.)
VB.NET은 대소 문자를 구분하지 않으므로이 field코드에서 보호 된 멤버에 액세스하는 간단한 방법은 없습니다 .
public class CSharpClass
{
protected int field;
public int Field { get { return field; } }
}
예를 들어 필드가 아닌 속성 getter에 액세스합니다.
Public Class VBClass
Inherits CSharpClass
Function Test() As Integer
Return Field
End Function
End Class
도대체 field소문자로 도 쓸 수 없습니다. VS 2010은 계속 수정합니다.
VB.NET에서 파생 클래스에 쉽게 액세스 할 수 있으려면 다른 명명 규칙이 필요합니다. 밑줄 접두어는 아마도 가장 덜 침입적이고 가장 "역사적으로 받아 들여지는"것입니다.
오래된 질문, 새로운 답변 (C #).
C #에 밑줄을 사용하는 또 다른 용도는 ASP NET Core의 DI (종속성 주입)입니다. readonly구성하는 동안 주입 된 인터페이스에 지정된 클래스의 개인 변수는 밑줄로 시작해야합니다. 클래스의 모든 개인 멤버에 대해 밑줄을 사용할지 여부는 논쟁의 여지가 있지만 (Microsoft 자체가 따르더라도) 확실합니다.
private readonly ILogger<MyDependency> _logger;
public MyDependency(ILogger<MyDependency> logger)
{
_logger = logger;
}
이와 같은 이름 지정 규칙은 코드, 특히 자신이 아닌 코드를 읽을 때 유용합니다. 강력한 이름 지정 규칙은 특정 멤버가 정의 된 위치, 멤버의 종류 등을 나타내는 데 도움이됩니다. 대부분의 개발 팀은 간단한 이름 지정 규칙을 채택하고 멤버 필드 앞에 밑줄 ( _fieldName)을 붙 입니다. 과거에는 C #에 대해 다음 이름 지정 규칙을 사용했습니다 (Reflector에서 볼 수있는 .NET 프레임 워크 코드에 대한 Microsoft의 규칙을 기반으로 함).
인스턴스 필드 : m_fieldName
정적 필드 : s_fieldName
퍼블릭 / 보호 / 내부 멤버 : PascalCasedName ()
프라이빗 멤버 : camelCasedName ()
이를 통해 사람들은 익숙하지 않은 코드를 매우 빠르게 읽을 때 구성원의 구조, 사용, 접근성 및 위치를 이해할 수 있습니다.