2011-08-07 9 views
6

Jest wiele pytań na temat SO lamentujących na tym, że Code Analysis reguła CA2000 jest stosowana zbyt rygorystycznie przez VS2010, ale wydaje mi się, że natknąłem się na przypadek, w którym należy go zastosować, ale nie jest.Dlaczego Bitmap powoduje regułę CA2000, ale obraz nie?

Rozważmy następujący kod:

Image srcImage = Image.FromFile(source); 
Bitmap newImage = new Bitmap(newWidth, newHeight); 

using (Graphics gr = Graphics.FromImage(newImage)) 
{ 
    gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight)); 
} 
newImage.Save(destination, ImageFormat.Jpeg); 

Teraz jeśli biegnę analizy kodu w Visual Studio 2010 na ten temat, to narzekają newImage nie są umieszczone (Easy Fix, umieścić go w innym wykorzystaniem bloku) , ale nie narzeka na srcImage (która również ma metodę Dispose(), której nigdy nie wywołuję). Czy ktoś wie, dlaczego analiza kodu nie narzeka tutaj?

Odpowiedz

0

Dobrze powinno „narzekają srcImage” zbyt jednak Chyba że nie narzekać, bo jesteś przekazaniem go do metody DrawImagegr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));”, więc albo nie jest wystarczająco inteligentny, aby wiedzieć, że nie będzie używał więcej akcji po zwróceniu metody, a może założył, że użyłeś jej w instancji gr, która zostanie usunięta. W każdym razie powinieneś użyć using dla srcImage, tak jak to, co robisz z newImage i nie postępuj zgodnie z analizą kodu w tym zakresie.

+0

Myślałem, że na początku, ale potem spojrzałem na inne pytania CA2000 na SO i prawie wszystkie z nich mają regułę uruchamianą przez takie przekazywanie argumentów innej funkcji (choć zwykle z zaangażowanymi konstruktorami). To dziwne, że reguła ta denerwująca (dla wielu ludzi, sądząc po liczbie pytań SO) byłaby tak wybaczająca w tej sytuacji. –

+0

Yup, zgadzam się, że jest to denerwujące, jednak powinniśmy "polubić Cię już", nie polegając na analizie kodu, aby naprawić nasze problemy z kodem, zamiast tego po prostu użyć ich do podwójnego sprawdzenia i zobaczyć, czy zapomnimy o czymś tu i tam ... –

+0

Tak ... ale ten rodzaj pokonuje cel takich narzędzi. Powodem, dla którego ich używam, jest to, że mogą wskazać lokalizacje, w których zrobiłem coś złego, aby zaoszczędzić mi kłopotów z przeglądaniem gigantycznych baz kodujących małe rzeczy takie jak ta. –

5

CA2000 i podobne/pokrewne zasady CA2213 (DisposableFieldsShouldBeDposed) i CA1001 (TypesThatOwnDisposableFieldsShouldBeDisposable) są raczej surowe, jeśli chodzi o sposób, w jaki rozpoznają "własność" produktu jednorazowego użytku. Biorą pod uwagę, że Twój kod jest właścicielem jednorazowej instancji, jeśli do utworzenia instancji bezpośrednio w kodzie wykorzystywany jest konstruktor instancji. Ponieważ używasz Image.FromFile do utworzenia instancji dla srcImage, reguła nie rozpoznaje Twojego kodu jako właściciela.

Jeśli nie zgadzasz się z tą zasadą, możesz utworzyć raport o błędzie pod numerem https://connect.microsoft.com/visualstudio/feedback. (Jeśli dbasz o zasady pola jednorazowego, możesz zagłosować na istniejącą propozycję https://connect.microsoft.com/VisualStudio/feedback/details/485291/typesthatowndisposablefieldsshouldbedisposable-rule-ca1001-is-too-permissive, gdy jesteś na tym.)

+0

Czy istnieje jakakolwiek zmiana w takiej metodzie, która mogłaby być naprawdę przydatna, bez cofania się i znakowania wielu metod z atrybutami wskazującymi, że powinny one być traktowane jako przejmowanie, rezygnacja lub fudging własności IDisposable (tj. Zmienne zachowanie w zależności od czynników narzędzie nie powinno być śledzone)? Wprowadzenie takiego zachowania może być opłacalne, ale dodanie wystarczającej ilości tagów do uzyskania czystych raportów może wymagać wiele pracy. – supercat

+0

@supercat: Jest całkiem możliwe, aby reguła została stworzona w taki sposób, aby wykryć, że wywoływana metoda jest metodą fabularną, która tworzy nową instancję jednorazowego użytku bez przechowywania tej instancji w jej własnym stanie. To powiedziawszy, reguła nie byłaby w stanie obsłużyć skomplikowanych wzorców tworzenia, takich jak używanie IoC bez dodawania pewnych metadanych. Jednak wszelkie atrybuty powinny dotyczyć metod fabrycznych, a nie ich konsumentów. –

+0

Jeśli skaner mógł zobaczyć kod dla fabryk, prawdopodobnie mógł określić, że tworzy i zwraca nowe instancje IDisposable.Nie wszystkie fabryki mają kod, który byłby dostępny dla skanera. Dodanie rozpoznania fabryk sprawiłoby, że skaner wygenerowałby bardziej użyteczne ostrzeżenia, ale także bardziej fałszywe, chyba że mógł również rozpoznać, czy obiekty umożliwiające identyfikację są legalnie przekazywane; takie uznanie spowodowałoby wiele trudnych problemów, chociaż ... – supercat

Powiązane problemy