2011-07-17 11 views

Odpowiedz

40

Dobrze according to the MSDNDWORD jest liczba całkowita bez znaku z zakresu od 0 do 4294967295.

Więc idealnie należy zastąpić go uint zamiast int.

Jednak, jak zauważyłeś, uint nie jest zgodny z CLS, więc jeśli twoja metoda jest publicznie widoczna, powinieneś użyć int i wykonać konwersję. W związku z tym, jeśli twoja metoda nie jest używana poza twoim zespołem, powinieneś oznaczyć ją jako internal zamiast public. Wtedy będziesz mógł użyć uint.

+0

myślę, co mnie martwi to, że jest to (1) niezgodne z ramami i (2) niezgodne z CLS. Czy powinienem to po prostu zignorować? – Mehrdad

2

Jest niepodpisany, więc zamapuj go na uint.

1

DWORD jest, według definicji (Microsoft), niepodpisaną 32-bitową liczbą całkowitą. Powinien mapować do dowolnego typu używanego przez kompilator do reprezentowania tego.

Obecnie jest to najprawdopodobniej niepodpisana int, ale nie jest to przenośna implementacja. Wiem, że używasz C#, ale aby dać przykład w języku Jestem bardziej zaznajomieni z typowa implementacja w C może być: Dotyczy

#if defined(SOME_HARDWARE_IMPLEMENTATION) 
#define DWORD unsigned int 
#elif #defined(SOME_OTHER_IMPLEMENTATION) 
#define DWORD unsigned long 
#elif #defined(YET_ANOTHER_IMPLEMENTATION) 
#define DWORD something_else 
#else 
#error Unsupported hardware; cannot map DWORD 
#endif 
+0

Jednak w języku C# 'uint' i' int' są 32-bitowymi liczbami całkowitymi. Masz jednak rację, że w C pierwotne typy danych, takie jak 'int' i' long', nie są spójne między kompilatorami. Jest to jednak problem tylko wtedy, gdy 'DWORD' jest używany w funkcji lub API nie zdefiniowanym przez Microsoft, gdzie według definicji' DWORD' jest 32-bitową liczbą całkowitą bez znaku. –

+0

C int i long są zawsze 32-bitowe w systemie Windows –

1

CLS ostrzeżenie zgodność tylko wtedy, gdy P/Invoke Metoda jest widoczna poza zbiorem, co ogólnie oznacza, że ​​połączenie jest publiczne. Jeśli metoda nie jest widoczna z zewnątrz, dopuszczalne jest użycie uint.

2

Użyj int. Powodem jest, jeśli zmienię "AutoRestartShell" z zmiennej uint:

regKey.SetValue("AutoRestartShell", uintVariable); 

typ danych w edytorze Registry zmiany do "REG_SZ". Jeśli mogę prosić o tej wartości mają być zwrócone z:

regKey.GetValue("AutoRestartShell"); 

ciąg zostanie zwrócony.

Jeśli jednak zmienić "AutoRestartShell" ze zmienną int:

regKey.SetValue("AutoRestartShell", intVariable); 

Typ danych pozostaje jako "REG_DWORD".

Dlaczego tak się dzieje? Brak pomysłu. Wiem tylko, że tak. Logika z pewnością powie nam, że powinno się używać uint, ale zmienia typ danych, których nie chcemy.

+0

Jak zachowanie lub całkowicie niezwiązana część .NET wiąże się z tworzeniem typu WinApi? – IllidanS4

+0

Z tego samego powodu, że dwie aplikacje nie mogą się ze sobą komunikować, wysyłając liczby całkowite, w których druga strona oczekuje ciągów i na odwrót. Jeśli chodzi o to, czy uint, czy int sprawiają, że tutaj jest prawdziwa różnica, nie wiem. To była tylko obserwacja. Pomyślałem, że najlepiej nie zmieniać tego, czego nie trzeba zmieniać. – Rehaan

+0

Wygląda na to, że winowajcą jest prywatna metoda * CalculateValueKind *. Po prostu nie uznaje 'uint', ale także nie zna" krótkich "lub innych typów liczbowych. Ale widzę, że publiczny interfejs API powinien obsługiwać typy zgodne z CLS, ważniejsze niż typy niezgodne z CLS. CLR faktycznie nie rozróżnia między 'int' i' uint'. – IllidanS4

0

Niestety, przeczytaj ewidencja musi używać int inaczej rzucać exception.this kod Microsoft:

private static void Get45or451FromRegistry() 
{ 
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\")) { 
     if (ndpKey != null && ndpKey.GetValue("Release") != null) { 
      Console.WriteLine("Version: " + CheckFor45DotVersion((int) ndpKey.GetValue("Release"))); 
     } 
     else { 
     Console.WriteLine("Version 4.5 or later is not detected."); 
     } 
    } 
} 

chociaż wydanie jest REG_DWORD

Powiązane problemy