2009-04-08 10 views
6

Próbuję dodać ograniczenie do ogólnej metody, aby sprawdzić wartości ValueTypes, ciągi znaków lub wartości wartości zerowalnych.Ogólne ograniczenie do ValueTypes, ciągów znaków i wartości zerowej wartości Typy

Problem polega na tym, że:

  • typy wartości są rozpórki
  • ciągi są niezmienne typy referencyjne
  • pustych są typy wartości, ale nie będą przyjmowane w „gdzie S: struct” typu ograniczeń .

Więc czy ktoś wie, czy istnieje sposób, że mogę zaakceptować te i tylko te typy w ogólnym ograniczeniu?

Problem polega na tym, że próbuję zaakceptować parametr Expression<Func<T, S>, który będzie reprezentował właściwość tych typów dla danego obiektu.

Funkcjonalność byłoby coś jak poniżej (uwaga kodu nie ma sensu i jest po prostu coś szybko zorientować się, czego szukam):

public class Person 
{ 
    public string Name {get; set;} 
    public DateTime? DOB {get; set;} 
    public int NumberOfChildren {get; set;} 
    public Car CurrentCar {get; set;} 
} 

--- 

internal void MyGenericMethod<T, S>(T myObject, Expression<Func<T, S> property){...} 

Person myPerson = new Person(); 
MyGenericMethod(myPerson, p => p.Name); //S would be a string 
MyGenericMethod(myPerson, p => p.DOB); //S would be a DateTime? 
MyGenericMethod(myPerson, p => p.NumberOfChildren); //S would be a struct 

Trzy połączeń powyżej powinny być akceptowane, ale nie co następuje:

MyGenericMethod(myPerson, p => p.CurrentCar); //S would be a class and shouldn't compile 

góry dzięki

UPDATE: Dzięki Anton i Marc. MyGenericMethod ma 4 różne sygnatury akceptujące dodatkowe parametry, dlatego nie podoba mi się pomysł stworzenia 3 różnych (struct, nullable, string) dla każdego z istniejących 4 ... to byłby koszmar do utrzymania!

Odpowiedz

7

Jedyne co mogę wymyślić to zestaw trzech funkcji (sans Expression<> stuff):

MyGenericFunction<T>(T t) 
    where T : struct 

MyGenericFunction<T>(T? t) 
    where T : struct 

MyGenericFunction(string s) 

UPDATE Zważywszy, że istnieją różne przeciążenia metody, mogę zasugerować:

class Holder 
{ 
    private object value; 

    public Holder(object value) 
    { 
     this.value = value; 
    } 

    public static implicit operator Holder(DateTime dt) 
    { 
     return new Holder(dt); 
    } 

    public static implicit operator Holder(string s) 
    { 
     return new Holder(s); 
    } 

    // Implicit conversion operators from primitive types 
} 

Zatem metoda staje

MyGenericMethod(Holder h); 

Nadal bardzo uciążliwy, ale mimo to może się udać.

+0

Może mieć sens, aby zdefiniować 'struct Holder'. Następnie staje się "syntaktycznym cukrem" kompilacyjnym, którego celem jest określenie, co jest i nie jest legalne. Ale wynik runtime byłby skuteczny - eliminuje przydział/usuwanie śmieci potrzebne dla klasy. – ToolmakerSteve

Powiązane problemy