2013-06-17 11 views
5

Stworzyłem klasę, która jest tylko w stanie obsłużyć pierwotne (lub ICloneable) RodzajeJak powiedzieć konstruktora należy używać tylko prymitywne typy

Chcę wiedzieć, czy jest możliwe, aby powiedzieć coś w stylu:

public myobject(primitiv original){...} 

czy naprawdę trzeba utworzyć konstruktor dla każdego rodzaju prymitywnego jak:

public myobject(int original){...} 
public myobject(bool original){...} 
... 

Co staram się osiągnąć to, aby utworzyć obiekt z 3 p publicznym wartości roperties, Original i IsDirty.
Wartość będzie głęboko Klon oryginał tak oryginalnego musi być primitve lub ICloneable

+0

Czy jesteś pewien, że dobrze zdefiniowano typ "pierwotny"? Specyfikacja języka C# wspomina o "typach prostych" (wszystkich strukturach), a także posiada pewne dodatkowe "typy predefiniowane", które są typami odniesienia (jak 'string'). –

+0

@JeppeStigNielsen dobre pytanie, o ile mogę powiedzieć, tak. Ale selfe made struct daje mi pewne bóle głowy. – WiiMaxx

+0

Na przykład, czy uważasz "System.UIntPtr' za" typ pierwotny "? Co jest specjalnego w tak zwanych "typach pierwotnych" w konkretnym scenariuszu? Nie mogłeś na przykład mieć "wartości" typu 'DateTime'? Jest to niezmienny typ wartości (i nie implementuje "ICloneable"). –

Odpowiedz

6

Pierwotne typu C# są zdefiniowane jako elemencie (realizowanych ogólnie ValueType w CLR NET). Wydaje mi się, że masz dwie możliwości:

  1. Jak już powiedziano: Odbierz dowolny typ, sprawdź go pod każdym akceptowanym typem, wyrzuć wyjątek, jeśli nie pasuje.
  2. Ustaw ogólną klasę, utwórz konstruktor generycznie z ograniczeniem where T : struct (z T jako parametrem typu). Spowoduje to wychwycenie wszystkich struktur, nie tylko typów pierwotnych, ale myślę, że jest to najlepsze, na co możesz liczyć bez ręcznego sprawdzania i sprawdzania kompilacji. Oczywiście możesz łączyć to ograniczenie z innymi.

I można połączyć dwie powyższe opcje, aby niektóre z kontroli zostały wykonane podczas kompilacji, a niektóre z nich zostały wykonane w czasie wykonywania.

+0

+1. Może to być najbardziej praktyczne rozwiązanie dla PO. Inne osoby dały to rozwiązanie, ale najlepiej to wyjaśniłeś. – Renan

6

Jeśli chcesz to zrobić, aby zmusić kogokolwiek jest za pomocą interfejsu API do korzystania z takich typów (poprzez kompilacji błędów czasowych powinny korzystać niewłaściwe typy), obawiam się, że nie da się tego zrobić.

Można było jednak otrzymać object w konstruktorze, ocenić jego rodzaj, a rzucić ArgumentException w przypadku parametr nie jest ani jednym z „prymitywnych” typów ani implementuje ICloneable.

Edytuj: To może być przydatne. Można określić, czy zmienna należy do pierwotnego typu z następującego kodu:

Type t = foo.GetType(); 
t.IsPrimitive; // so you don't have to do an evaluation for each primitive type. 
+1

+1 ale nie zapomnij sprawdzić, czy 'foo! = Null' (i być może wyrzucając' ArgumentNullException') przed wywołaniem 'foo.GetType()'. – hvd

+0

mhh Wiem o tym, ale to naprawdę nie pomaga osiągnąć 'myobject (primitiv original)' – WiiMaxx

2

to nie jest dokładnie to, o co prosiłeś, ale można mieć 2 konstruktorów, jeden na elemencie i jeden dla ICloneable:

public myobject(System.ValueType original){...} 
public myobject(ICloneable original){...} 
+0

'DateTime' i' TimeSpan' nie są prymitywami, ale przechodzą przez ten pierwszy konstruktor. – Renan

+0

@Renan Wiem, że pytanie wspomina o typach "prymitywnych", ale autor wspomniał również, że chce "głębokiego klonu oryginału". – Corneliu

+0

@Renan wow Myślałem, że jest prymitywne, więc ta odpowiedź nadal będzie pasować, więc będę badać o ValueType – WiiMaxx

-2

Co powiecie na generyczne zamiast na odbicie?

public class MyObject<T> 
    where T: IComparable 
{ 
    public MyObject(T original) 
    { 
     // do runtime check 
    } 
} 


var c1 = new MyObject<int>(1); 
// or 
var c2 = new MyObject<Int32>(2); 
+0

i jak mogę prosić o prymitywne? ponieważ prymitywne typy nie mają ICloneable – WiiMaxx

+2

Int32 nie implementuje ICloneable dla ex. – Corneliu

+0

więc zmień IClonable na struct, ponieważ ktoś już wskazał, że prymitywy są zdefiniowane jako structs. –

Powiązane problemy