2015-12-30 28 views
5

Bir veritabanından çeşitli verileri çekmesi beklenen bir çirkin yönteme sahibim ve bunu kullanmak için istenen türde bir nesne oluşturun. Amaç, çeşitli çirkinliği tek bir yere çekmektir, böylece bu yöntemi içeren sınıftan türeyen sınıflar nispeten temiz olabilir.Geri dönüş türü genel bir arabirim olduğunda, bir nesneyi genel bir döndürme türüne nasıl atarsınız?

Ben türü null olduğunda bile, tek bir nesneyi döndürmek gerekiyordu zaman ile ilgili bir sorun olmayacağım

:

protected T getValue<T>(ParameterObject myParameterObject) 
{ 
    var typeOfT = typeof (T); 

    if (typeOfT == typeof(bool)) 
    { 
     string val = this.getValue(myParameterObject); 

     if (val == null) 
      return default(T); 

     bool rVal; 
     if (!Boolean.TryParse(val, out rVal)) 
      return default(T); 

     return changeType<T>(rVal); 
    } 

    if (typeOfT == typeof (double?)) 
    { 
     string val = this.getValue(myParameterObject); 

     if (val == null) 
      return default(T); 

     double rVal; 
     if (!Double.TryParse(val, out rVal)) 
      return default(T); 

     return changeType<T>(rVal); 
    } 

    [...] 
} 

public static T changeType<T>(object value) 
{ 
    var t = typeof(T); 
    if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Nullable<>)) 
     return (T)Convert.ChangeType(value, t); 

    if (value == null) 
     return default(T); 

    t = Nullable.GetUnderlyingType(t); 
    return (T)Convert.ChangeType(value, t); 
} 

Ne yazık ki, benim istenen dönüş tipi ılist, olduğu durumlarla var o bir nesne değil, T. örneğidir var Ama changeType() işlevi bir hata ile başarısız olduğu için, ben bir rVal döndüremez

protected T getValue<T>(ParameterObject myParameterObject) 
{ 
    var typeOfT = typeof (T); 

    if (typeOfT.IsGenericType) 
    { 
     if (typeOfT.GetGenericTypeDefinition() == typeof (IList<>)) 
     { 
      var genericArgumentType = typeOfT.GenericTypeArguments.FirstOrDefault(); 
      var baseType = typeof (List<>); 
      var genericType = baseType.MakeGenericType(new[] {genericArgumentType}); 

      var rVal = Activator.CreateInstance(genericType); 

      [code to populate the list] 

      return changeType<T>(rVal); 
     } 

    [...] 
} 

:

System.InvalidCastException: Object must implement IConvertible.

bir Listesini dönmek istiyorum

Bu nedenle, dönüş türünün IList olduğu genel bir yöntemim var ve bir Liste olan bir nesneyim var, ancak benim başvurum Nesne türündedir. Bunu işlevinden döndürmek için nasıl yayınlarım? senin value nesne IConvertible uygulamıyor çünkü

+2

Eğer bariz bir şey eksik olursam özür dilerim, ama neden dönüş yapıyorsanız, türkçe (rVal); 'yerine' return (T) (object) rVal; '? – 31eee384

cevap

1

Sizin return (T)Convert.ChangeType(value, t); çizgi başarısız oluyor. MSDN docs

[...] For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. The method requires that conversion of value to conversionType be supported.

Bunu düzeltmek için

, ben genel bir yolu emin değilim ama bir IEnumerable veya IEnumerable<> Çeşidi value olmanın belirli bir durum için, o zaman gerçekleştirmek ardından döküm deneyebilirsiniz bir value.Select(x => changeType<ListGenT>(x)) linq sorgusu. changeType yönteminizi yinelemeli olarak kullanarak bu yuvalanmış genel türleri de ele almalıdır.

+0

Hala anladığımdan emin değilim, ancak List Listesini oluşturmak ve bir IList döndürmek yerine, yöntemlerimi dönmek için değiştirdiysem sorun giderildi. –

İlgili konular