2009-04-08 16 views
6

Genel bir yönteme kısıtlama eklemeye çalışıyorum, bu nedenle ValueTypes, Strings veya Nullable değer türlerini kontrol eder.ValueTypes, Dizeleri ve Null Değerli Değerler için Genel kısıtlama

sorun şudur:

  • değer türleri dikmeler
  • dizeleri değişmez referans tipleri
  • null are değer türleri vardır ama bir "S: struct" kabul edilmeyecektir tipi kısıtlaması .

Ayrıca, bunları kabul etmenin bir yolu olup olmadığını ve genel bir kısıtlamada yalnızca bu türlerin olup olmadığını bilen var mı?

Sorun, belirli bir nesne için bu türlerin bir özelliğini temsil edecek bir Expression<Func<T, S> parametresini kabul etmeye çalışıyorum.

işlevselliği gibi bir şey olurdu (herhangi bir anlam ifade etmiyor kodunu not edin ve ben aradığım bir fikir edinmek için hızlı sadece bir şeydir) Aşağıdaki:

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 

üç aramalar yukarıdaki tüm kabul edilir ancak şu değil edilmelidir: Teşekkür Anton ve Marc:

GÜNCELLEME peşin

yılında

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

teşekkür ederiz. MyGenericMethod, ekstra parametreleri kabul eden 4 farklı imzaya sahiptir, bu yüzden mevcut 4'ün her biri için 3 farklı (struct, nullable, string) yaratma fikrini sevmiyorum ... ki bu, korumak için bir kabus olurdu! Ben ile gelebilir

cevap

7

tek şey üç fonksiyonları (sans Expression<> şeyler) kümesidir: bir yöntemin çeşitli aşırı yükler olduğunu göz önüne alındığında

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

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

MyGenericFunction(string s) 

UPDATE, ben önerebilirsiniz:

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 
} 

Böylece sizin yöntem

MyGenericMethod(Holder h); 
olur

Hala çok hantal, ama yine de işe yarayabilir.

+0

Bunun yerine struct struct öğesini tanımlamak mantıklı olabilir. Sonra, derleme zamanı "sözdizimsel şeker" haline gelir ve amacı neyin yasal olup olmadığını belirtmektir. Ancak çalışma zamanı etkinliği verimli olacaktır - bir sınıf için gereken tahsis/çöp toplama işlemini ortadan kaldırır. – ToolmakerSteve