C #에서 "사용되지 않음"및 "할당되지 않음"경고 표시 안 함


107

기본적으로 관리 코드에서 사용하기 위해 이전 Windows ISAPI를 설명하는 C # 프로젝트에 HTTPSystemDefinitions.cs 파일이 있습니다.

여기에는 전부가 아니거나 코드에서 사용되는 ISAPI와 관련된 전체 구조 집합이 포함됩니다. 컴파일시 이러한 구조의 모든 필드 멤버는 다음과 같은 경고를 발생시킵니다.

경고 필드 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader'는 할당되지 않으며 항상 기본값이 null입니다.

또는

경고 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus'필드는 사용되지 않습니다.

로 비활성화 할 수 있습니까 #pragma warning disable? 그렇다면 해당 오류 번호는 무엇입니까? 내가 할 수있는 다른 것이 없다면? 이 파일에 대해이 작업을 수행하는 작업 만, 다른 파일에서 이러한 경고를받는 것이 중요합니다.

편집하다

예제 구조체 :-

struct HTTP_FILTER_PREPROC_HEADERS
{
    //
    //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
    //  Header names should include the trailing ':'.  The special values
    //  'method', 'url' and 'version' can be used to retrieve the individual
    //  portions of the request line
    //

    internal GetHeaderDelegate GetHeader;
    internal SetHeaderDelegate SetHeader;
    internal AddHeaderDelegate AddHeader;

    UInt32  HttpStatus;               // New in 4.0, status for SEND_RESPONSE
    UInt32  dwReserved;               // New in 4.0
}

해당 필드의 선언을 표시 할 수 있습니까? 아니면 해당 필드가있는 구조체를 표시 할 수 있습니까? 즉. 예를 들어주세요.
Lasse V. Karlsen

11
이것이 interop 정의라면 일반적으로 [StructLayout(LayoutKind.Sequential)]메모리 레이아웃이 올바른지 확인해야합니다 (현재 구현에서는이 속성이 없어도되지만 AFAIK는 보장되지 않습니다). 올바르게 기억하면 C # 컴파일러는이 특성의 존재를 감지하고 interop을 위해 필드가 있어야한다는 것을 알고 있으므로 이러한 경고를 자동으로 억제합니다. (나는 이것에 대해 틀릴 수 있으므로 답변 대신 댓글로 게시합니다).
Greg Beech

@Greg : 유용한 정보입니다. 조사하겠습니다. 경고를 억제하는 것보다 생성하지 않는 것이 좋습니다.
AnthonyWJones

1
사용하는 일 StructLayout. 경고 자체를 억제하는 것보다 깨끗해 보입니다.
디아나

@GregBeech 당신이 맞아요! VS2017의 .NET Standard 프로젝트에는 여전히 적용됩니다.
zwcloud

답변:


195

네, 억제 할 수 있습니다.

일반적으로 나는 경고를 억제하는 것을 반대하지만,이 경우 interop에 사용되는 구조체는 절대로 사용할 의도가 없거나 사용할 수 없더라도 일부 필드가 반드시 있어야하므로이 경우에는 정당화되어야한다고 생각합니다. .

일반적으로이 두 가지 경고를 표시하지 않으려면 문제가되는 코드를 수정합니다. 첫 번째 ( "... 사용되지 않음")는 일반적으로 이전 버전의 코드에서 남은 코드 냄새입니다. 코드가 삭제되었지만 필드가 남아있을 수 있습니다.

두 번째는 일반적으로 잘못 사용 된 필드에 대한 코드 냄새입니다. 예를 들어 속성의 새 값을 다시 속성 자체에 잘못 쓰고 백업 필드에는 쓰지 않을 수 있습니다.


" Field XYZ is never used "에 대한 경고를 표시하지 않으려면 다음을 수행하십시오.

#pragma warning disable 0169
... field declaration
#pragma warning restore 0169

" 필드 XYZ가 할당되지 않고 항상 기본값 XX "에 대한 경고를 표시하지 않으려면 다음을 수행하십시오.

#pragma warning disable 0649
... field declaration
#pragma warning restore 0649

이러한 경고 번호를 직접 찾으려면 (예 : 0169 및 0649를 사용하는 방법을 어떻게 알았습니까) 다음과 같이하십시오.

  • 코드를 정상적으로 컴파일하면 Visual Studio의 오류 목록에 몇 가지 경고가 추가됩니다.
  • 출력 창과 빌드 출력으로 전환하고 동일한 경고를 찾습니다.
  • 다음과 같은 관련 메시지에서 4 자리 경고 코드를 복사합니다.

    C : \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs ( 10,28 ) : warning CS 0649 : 'ConsoleApplication19.Program.dwReserved'필드는 할당되지 않으며 항상 기본값 0을 갖습니다.


주의 사항 : @Jon Hanna 의 의견에 따르면,이 질문과 답변의 향후 발견 자에게 몇 가지 경고가 필요할 것입니다.

  • 우선, 경고를 억제하는 행위는 두통 때문에 약을 삼키는 것과 유사합니다. 물론, 때때로하는 것이 옳은 일일 수도 있지만, 포괄적 인 해결책은 아닙니다. 때때로 두통은 경고와 마찬가지로 가리지 않아야하는 실제 증상입니다. 빌드 출력에서 ​​경고를 맹목적으로 제거하는 대신 원인을 수정하여 경고를 처리하는 것이 항상 가장 좋습니다.
  • 경고를 표시하지 않으려면 위에서 설명한 패턴을 따르십시오. 첫 번째 코드 줄 은 해당 파일의 나머지 부분에 대한#pragma warning disable XYZK 경고 비활성화 하거나 적어도 해당 파일을#pragma warning restore XYZK 찾을 때까지 경고 비활성화합니다 . 이러한 경고를 비활성화하는 줄 수를 최소화하십시오. 위의 패턴은 한 줄에 대한 경고를 비활성화합니다.
  • 또한 Jon이 언급했듯이이 작업을 수행하는 이유에 대한 설명은 좋은 생각입니다. 경고를 비활성화하는 것은 원인없이 수행 할 때 분명히 코드 냄새이며, 주석은 향후 관리자가 왜 그렇게했는지 궁금해하거나 제거하고 경고를 수정하는 데 시간을 소비하는 것을 방지합니다.

9
위의 답변에 더 나아가 비활성화의 범위를 가능한 한 작게 (유용한 곳에서 비활성화하는 것을 방지하기 위해)하고 비활성화하는 이유에 대한 설명과 함께 비활성화를 항상 동반하는 것이 좋습니다 //exists for interop. 이 경우.
Jon Hanna

감사합니다. VS가 오류 목록 창에 이러한 숫자에 대한 열을 포함하지 않는다는 것은 이상한 선택입니다.
AnthonyWJones

2
Jon이 말했듯이 "이유"를 언급하는 것은 매우 중요합니다. 또한 일반적으로 경고 메시지 텍스트의 일부를 주석에 추가합니다. 예를 들어 // Suppress "is never assigned to ..."경고. 경고 코드를 찾아야하는 번거 로움으로부터 미래의 관리자를 구하십시오. 결국 그것은 당신 일 수 있습니다!
Tom Bushell

1
당장 명확하지는 않지만 CTRL + F를 통해 출력 창에서 찾기를 사용하고 "경고"를 입력하고 "모두 찾기"를 클릭하면 경고 번호가 표시된 모든 경고를 빠르게받을 수 있습니다. 그것은 그 [StructLayout(LayoutKind.Sequential)]속성이 질문에 대한 Greg Beech의 의견에 따라 interop을 훨씬 잘 처리 한다고 말했습니다 .
Ryan Buddicom 2014

2
Unity3D 사용자의 경우 경고 번호는 비공개 필드의 경우 0414이고 로컬 변수의 경우 0219이며 169 (대신 경고를 복원 할 수 없다는 경고가 표시됨)가 아닙니다.
Draco18s은 더 이상 SE 신뢰하지

14

이러한 경고를 수정하는 또 다른 "솔루션"은 struct를 만드는 것 public입니다. 그러면 컴파일러가 필드가 어셈블리 외부에서 사용 (할당)되는지 여부를 알 수 없기 때문에 경고가 발생하지 않습니다.

즉, "interop"구성 요소는 일반적으로 공개가 아니라 internal또는 private.


2
좋습니다. 이렇게하면 경고 가 숨겨집니다.하지만 structas 와 같은 설정은 우리가 숨기려는 경고 public보다 실수 일 가능성이 더 큽니다. (내부 구현에 사용되는 유형을 불필요하게 노출해서는 안되며 공용 필드가있는 유형은 공용 API에 속하지 않을 수 있습니다.) 그러한 유형이 "차라리 internal또는 private";-) 이어야한다는 귀하의 조언을 강화하기 위해 .
binki

굉장한 감사합니다-이것이 제가 필요한 것입니다. 나는 사용 JsonConvert.DeserializeObject하고 있으며 모든 속성이 노출 된 공용 클래스로 역 직렬화하여 반환되는 내용을 알고 있습니다. 모든 공개 문자열로 비어있는 공개 클래스로 만드는 것만으로도 멋진 짧은 코드이며 이제 더 이상 경고가 없습니다. 배열에있는 내용을 명시 적으로 명시 할 필요가 없기 때문에 동적 클래스를 사용하는 것이 더 좋을 수도 있지만, 객체를 사용하려는 모든 사람에게 좋은 참조가 될 것이라고 생각합니다.
user1274820

6

구현 골격을 생성하기 위해 VS를 얻었 System.ComponentModel.INotifyPropertyChanged으며 이벤트는 CS0067 경고를 트리거 한 필드로 구현되었습니다.

허용 된 답변에 제공된 솔루션의 대안으로 필드를 속성으로 변환하고 경고가 사라졌습니다 .

이는 속성 선언 구문 설탕이 필드와 필드를 참조하는 getter 및 / 또는 setter 메서드 (내 경우에는 추가 / 제거)로 컴파일되기 때문에 의미가 있습니다. 이것은 컴파일러를 만족시키고 경고가 발생하지 않습니다.

struct HTTP_FILTER_PREPROC_HEADERS
{
    //
    //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
    //  Header names should include the trailing ':'.  The special values
    //  'method', 'url' and 'version' can be used to retrieve the individual
    //  portions of the request line
    //

    internal GetHeaderDelegate GetHeader {get;set;}
    internal SetHeaderDelegate SetHeader { get; set; }
    internal AddHeaderDelegate AddHeader { get; set; }

    UInt32 HttpStatus { get; set; }               // New in 4.0, status for SEND_RESPONSE
    UInt32 dwReserved { get; set; }               // New in 4.0
}

솔루션은 경고를 비활성화하는 것보다 훨씬 우아하지만 일부 필드 전용 속성 (예 : MarshalAsAttribute)을 방해 할 수 있습니다.
HuBeZa 2012

1
정보 :이 상황에서 생성 된 실제 개인 필드에는 <GetHeader>k__BackingField사용 된 C # 컴파일러의 구현 세부 정보에 따라 와 같은 "이상한"이름이있을 수 있습니다 .
Jeppe Stig Nielsen

1

C / C ++ 사용자는 (void)var;사용하지 않는 변수 경고를 억제 해야 합니다. 방금 비트 연산자를 사용하여 C #에서 사용하지 않는 변수 경고를 억제 할 수 있음을 발견했습니다.

        uint test1 = 12345;
        test1 |= 0; // test1 is still 12345

        bool test2 = true;
        test2 &= false; // test2 is now false

두 식 모두 VS2010 C # 4.0 및 Mono 2.10 컴파일러에서 사용되지 않는 변수 경고를 생성하지 않습니다.


4
에서 작동 uint하지만 다른 유형에서는 작동 하지 않습니다 Exception. C / C ++에 해당하는 일반적인 트릭을 알고 var;있습니까?
manuell 2015

1
@manuell 안녕하세요! 다음 error.ToString();유형의 변수에 사용할 수 있습니다.Exception
Sv443

지금부터 감사합니다. 그 트릭은 런타임에 실제 코드를 추가합니다.
manuell 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.