C # 'da "asla kullanılmaz" ve "asla atanmaz" uyarılarının bastırılması


107

C # projesinde bir HTTPSystemDefinitions.cs dosyam var, temelde eski Windows ISAPI'yi yönetilen kod tarafından tüketim için açıklıyor.

Bu, tümü olmayan veya kod tarafından tüketilen ISAPI ile ilgili tüm Yapı setini içerir. Derlemede bu yapıların tüm saha üyeleri aşağıdaki gibi bir uyarıya neden oluyor: -

Uyarı Alanı 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' asla atanmaz ve her zaman varsayılan değeri null olacaktır

veya

Uyarı 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' alanı asla kullanılmaz

Bunlar ile devre dışı bırakılabilir #pragma warning disablemi? Öyleyse, ilgili hata numaraları ne olur? Yoksa yapabileceğim başka bir şey var mı? Bunu sadece bu dosya için ne yapacağımı, diğer dosyalardan gelen bu gibi uyarıları görmem önemli olduğunu unutmayın.

Düzenle

Örnek yapı: -

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
}

Bu alanların bildirimini veya daha doğrusu içinde bulundukları yapıyı gösterebilir misiniz? yani. örnek vermek.
Lasse V.Karlsen

11
Bunlar birlikte çalışma tanımlarıysa, normalde [StructLayout(LayoutKind.Sequential)]bellek düzeninin doğru olduğundan emin olmak için koyarsınız (mevcut uygulamada bu öznitelik olmadan bile olacaktır, ancak AFAIK garanti edilmez). Doğru hatırlıyorsam, C # derleyicisi bu özniteliğin varlığını algılar ve alanların birlikte çalışma için orada olması gerektiğini bildiği için bu uyarıları otomatik olarak bastırır. (Bu konuda yanılıyor olabilirim, dolayısıyla bir cevap yerine yorum olarak yayınlayabilirim).
Greg Beech

@Greg: Bu, araştıracağım yararlı bir bilgi. Uyarının bastırmak yerine oluşturulmamasını tercih ederim.
AnthonyWJones

1
Kullanmak için +1 StructLayout. Uyarıları bastırmaktan daha temiz görünüyor.
Deanna

@GregBeech Haklısınız! Bu, VS2017'deki .NET Standard projeleri için hala geçerlidir.
zwcloud

Yanıtlar:


195

Evet, bunlar bastırılabilir.

Normalde, uyarıları bastırmaya karşıyım, ancak bu durumda, birlikte çalışma için kullanılan yapılar, onları asla kullanmak istemeseniz (veya kullanamasanız bile) kesinlikle bazı alanların mevcut olmasını gerektirir, bu nedenle bu durumda bunun gerekçelendirilmesi gerektiğini düşünüyorum. .

Normalde, bu iki uyarıyı bastırmak için, rahatsız edici kodu düzeltmeniz gerekir. İlki ("... asla kullanılmaz") genellikle kodun önceki sürümlerinden kalanların bir kod kokusudur. Belki kod silindi, ancak alanlar geride kaldı.

İkincisi genellikle yanlış kullanılan alanlar için bir kod kokusudur. Örneğin, bir özelliğin yeni değerini yanlış bir şekilde özelliğin kendisine geri yazabilir, asla destek alanına yazmayabilirsiniz.


" XYZ Alanı asla kullanılmaz " uyarılarını engellemek için şunu yaparsınız:

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

" XYZ alanına hiçbir zaman atanmaz ve her zaman varsayılan değeri XX olacaktır " için uyarıları engellemek için şunu yaparsınız:

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

Bu tür uyarı numaralarını kendiniz bulmak için (ör. 0169 ve 0649'u kullanmayı nasıl bildim), şunu yapın:

  • Kodu normal şekilde derleyin, bu, Visual Studio'daki hata listenize bazı uyarılar ekler
  • Çıktı penceresine ve Derleme çıktısına geçin ve aynı uyarıları arayın
  • Aşağıdaki gibi görünmesi gereken ilgili mesajdan 4 basamaklı uyarı kodunu kopyalayın:

    C: \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs (10,28): uyarı CS 0649 : 'ConsoleApplication19.Program.dwReserved' alanına hiçbir zaman atanmaz ve her zaman varsayılan değeri 0 olur


Uyarı : @ Jon Hanna'nın yorumuna göre , bu soru ve cevabın gelecekteki bulucuları için bunun için belki de birkaç uyarı olabilir.

  • Birincisi ve en önemlisi, bir uyarıyı bastırma eylemi, baş ağrısı için hapları yutmaya benzer. Elbette, bazen yapılması gereken doğru şey olabilir, ancak her şeyi kapsayan bir çözüm değildir. Bazen baş ağrısı, uyarılarda olduğu gibi maskelememeniz gereken gerçek bir semptomdur. Uyarıları yapı çıktısından körü körüne kaldırmak yerine, nedenlerini gidererek tedavi etmeye çalışmak her zaman en iyisidir.
  • Bunu söyledikten sonra, bir uyarıyı bastırmanız gerekirse, yukarıda ortaya koyduğum modeli takip edin. İlk kod satırı, o dosyanın geri kalanı için veya en azından bir karşılık gelen bulunana kadar #pragma warning disable XYZKuyarıyı devre dışı bırakır . Bu uyarıları devre dışı bıraktığınız satır sayısını en aza indirin. Yukarıdaki desen, yalnızca bir satır için uyarıyı devre dışı bırakır.#pragma warning restore XYZK
  • Ayrıca, Jon'un da bahsettiği gibi, bunu neden yaptığınıza dair bir yorum yapmak iyi bir fikir. Bir uyarıyı devre dışı bırakmak, sebepsiz yapıldığında kesinlikle bir kod kokusudur ve bir yorum, gelecekteki bakımcıların neden yaptığınızı merak ederek veya hatta onu kaldırıp uyarıları düzeltmeye çalışarak zaman harcamalarını önleyecektir.

9
Yukarıdaki yanıta ek olarak, devre dışı bırakmanın kapsamının olabildiğince küçük olmasını (yararlı olduğu bir yerde devre dışı bırakmaktan kaçınmak için) ve devre dışı bırakmanın her zaman neden devre dışı bıraktığınıza dair bir yorumla eşlik etmesini tavsiye ederim //exists for interop. bu durum.
Jon Hanna

Çok teşekkürler. VS'nin Hata Listesi penceresinde bu numaralar için bir sütun içermemesi garip bir seçim.
AnthonyWJones

2
Jon'un dediği gibi, "neden" hakkında yorum yapmak çok önemli. Ek olarak, genellikle uyarı mesajının metninin en azından bir kısmını yoruma eklerim örn. // Bastır "asla atanmaz ..." uyarısı. Gelecekteki bakımcıları uyarı koduna bakma sıkıntısından kurtarın - sonuçta bu siz olabilirsiniz!
Tom Bushell

1
Hemen belli olmamakla birlikte CTRL + F ile Çıktı penceresinde Bul'u kullanabilir, "uyarı" yazabilir, "Tümünü Bul" seçeneğine tıklayabilir ve her uyarıyı hızlı bir şekilde, görüntülenen uyarı numaraları ile alabilirsiniz. [StructLayout(LayoutKind.Sequential)]Greg Beech'in soru hakkındaki yorumuna göre niteliğin birlikte çalışmayı çok daha iyi ele aldığını söyledi .
Ryan Buddicom

2
Unity3D kullanıcıları için uyarı numaralarının özel alanlar için 0414 ve yerel değişkenler için 0219 olduğu, 169 değil (bunun yerine uyarıyı geri yükleyememe konusunda bir uyarı attığı) yorumunda bulunulur.
Draco18'ler artık SE

14

Bu uyarıları düzeltmek için başka bir "çözüm" yapıyı yapmaktır public. Bu durumda uyarılar verilmez çünkü derleyici alanların derleme dışında kullanılıp kullanılmadığını (atanıp atanmadığını) bilemez.

Bununla birlikte, "birlikte çalışma" bileşenleri genellikle herkese açık olmamalıdır, bunun yerine internalveya private.


2
Güzel, bu gizlemek uyarı yapar ... ama böyle bir ayar structolarak publicbiz maskelemek için çalışıyoruz uyarı daha bir hata olması daha olasıdır. (Muhtemelen, dahili uygulama için kullanılan türleri gereksiz yere göstermemelisiniz ve genel alanlara sahip türler muhtemelen genel bir API'ye ait değildir). Sadece bu tür türleri “yerine olması gerektiğini senin tavsiye güçlendirmek için internalveya private” ;-).
binki

harika teşekkürler - ihtiyacım olan buydu. Ben kullanıyorum JsonConvert.DeserializeObjectve ben sadece iade edilecektir bilmek böylece açıkta özelliklerin hepsi var bir kamu sınıfa deserializing ediyorum. Sadece onu tüm genel dizelerle boş olan genel bir sınıf yapmak güzel bir kısa kod ve artık uyarı yok. Belki dinamik bir sınıf kullanmak dizide ne olduğunu açıkça belirtmeniz gerekmediğinden daha iyi olabilir, ancak bence bu nesneyi kullanmayı uman herkes için güzel bir referans olacaktır.
user1274820

6

Uygulama iskeletini oluşturmak System.ComponentModel.INotifyPropertyChangediçin VS'yi aldım ve olaylar CS0067 uyarılarını tetikleyen alanlar olarak uygulandı.

Kabul edilen cevapta verilen çözüme alternatif olarak alanları özelliğe dönüştürdüm ve uyarı ortadan kalktı .

Bu mantıklıdır, çünkü şeker özellik bildirimleri sözdizimi bir alana ek olarak alana başvuran alıcı ve / veya ayarlayıcı yöntemlere (benim durumumda ekle / kaldır) derlenir. Bu, derleyiciyi tatmin eder ve uyarılar ortaya çıkmaz:

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
}

Çözümünüz, uyarıyı devre dışı bırakmaktan çok daha zariftir, ancak yalnızca bazı alan özellikleriyle, örneğin MarshalAsAttribute ile çakışabilir.
HuBeZa

1
Bilgi: Bu durumda oluşturulan gerçek özel alanlar <GetHeader>k__BackingField, kullanılan C # derleyicisinin uygulama ayrıntılarına bağlı olarak "garip" adlara sahip olabilir .
Jeppe Stig Nielsen

1

C / C ++ kullanıcıları, (void)var;kullanılmayan değişken uyarılarını bastırmak zorundadır . Bitsel operatörlerle C # 'da kullanılmayan değişken uyarılarını da bastırabileceğinizi yeni keşfettim:

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

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

Her iki ifade de VS2010 C # 4.0 ve Mono 2.10 derleyicilerinde kullanılmayan değişken uyarıları üretmez.


4
İçin çalışır uint, ancak diğer türler için değil Exception. C / C ++ ile eşdeğer genel bir numara biliyor musunuz var;?
manuell

1
@manuell gelecekten merhaba! Bir error.ToString();tür değişkeni için kullanabilirsinizException
Sv443

Şimdiden teşekkürler. Bu numara çalışma zamanında gerçek kod ekler, değil mi?
manuell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.