2013-06-28 12 views
6

I unten Methode mit follwing Anforderung schrieb -Generisches Verfahren Nullable Type Rückgabewerte

  1. Eingang ist xmlnode und attribute
  2. Rückkehr der Wert, wenn es mit dem zugehörigen Attributnamen
  3. weitergegeben gefunden
  4. Wenn in attributeName kein Wert übergeben wird, sollte er zurückgeben -

    3.1. Für int -1 3.2. Für Datetime DateTime.MinValue 3.3. Für String, null 3.4. Für bool, null

Unten Methode schlägt für Fall 3.4.

public T AttributeValue<T>(XmlNode node, string attributeName) 
     { 
      var value = new object(); 

      if (node.Attributes[attributeName] != null && !string.IsNullOrEmpty(node.Attributes[attributeName].Value)) 
      { 
       value = node.Attributes[attributeName].Value; 
      } 
      else 
      { 

       if (typeof(T) == typeof(int)) 
        value = -1; 
       else if (typeof(T) == typeof(DateTime)) 
        value = DateTime.MinValue; 
       else if (typeof(T) == typeof(string)) 
        value = null; 
       else if (typeof(T) == typeof(bool)) 
        value = null; 



      } 
      return (T)Convert.ChangeType(value, typeof(T)); 
     } 

Wenn Änderung

dies
public System.Nullable<T> AttributeValue<T>(XmlNode node, string attributeName) where T : struct 
     { 
      var value = new object(); 

      if (node.Attributes[attributeName] != null && !string.IsNullOrEmpty(node.Attributes[attributeName].Value)) 
      { 
       value = node.Attributes[attributeName].Value; 
      } 
      else 
      { 

       if (typeof(T) == typeof(int)) 
        value = -1; 
       else if (typeof(T) == typeof(DateTime)) 
        value = DateTime.MinValue; 
       else if (typeof(T) == typeof(string)) 
        return null; 
       else if (typeof(T) == typeof(bool)) 
        return null; 



      } 
      return (T?)Convert.ChangeType(value, typeof(T)); 
     } 

Es schlägt fehl, für einige Hilfe-String-Typ d Fall 3,3

Wir freuen uns.

+0

Wie _call_ Sie die Methode in Ihrem ersten Satz von Code? Sie müssten es als 'AttributeValue (...)' aufrufen. Wenn Sie nur 'AttributValue (...)' aufrufen, dann ist 'null' kein gültiger Wert für' bool'. EDIT: Und Ihr zweiter Fall schlägt fehl, weil 'string' nicht für' System.Nullable 'verwendet werden kann, da' string' keine Struktur vom Werttyp ist. –

Antwort

4

Dank für eine Reihe von Antworten, ist es das, was ich geschrieben habe und es funktioniert für mich ..

Es ist für die Typen null zurückgibt.

public T AttributeValue<T>(XmlNode node, string attributeName) 
     { 
      object value = null; 

      if (node.Attributes[attributeName] != null && !string.IsNullOrEmpty(node.Attributes[attributeName].Value)) 
       value = node.Attributes[attributeName].Value; 

      if (typeof(T) == typeof(bool?) && value != null) 
       value = (string.Compare(value.ToString(), "1", true) == 0).ToString(); 

      var t = typeof(T); 
      t = Nullable.GetUnderlyingType(t) ?? t; 

      return (value == null) ? 
       default(T) : (T)Convert.ChangeType(value, t); 
     } 

Ich nenne es wie dieses

const string auditData = "<mydata><data><equipmentStatiticsData><userStatistics maxUsers='100' totalUsers='1' authUsers='0' pendingUsers='' adminAddedUsers='' xmlUsers='' internalDBUsers='' webUsers='' macUsers='' vpnUsers='' xUsers8021=''></userStatistics><equipmentStatistics cpuUseNow='14' cpuUse5Sec='1' cpuUse10Sec='1' cpuUse20Sec='1' ramTotal='31301632' ramUtilization ='1896448' ramBuffer='774144' ramCached='8269824' permStorageUse='24' tempStorageUse='24'></equipmentStatistics><authStatus status='1'></authStatus></equipmentStatiticsData></data></mydata>"; 
    xmlDoc.LoadXml(auditData); 
    var userStatsNode = xmlDoc.SelectSingleNode("/mydata/data/equipmentStatiticsData/userStatistics"); 


    var intNullable = AttributeValue<int?>(userStatsNode, "vpnUsers"); 
    var nullableBoolTrue = AttributeValue<bool?>(userStatsNode, "totalUsers"); 
    var nullableBoolFalse = AttributeValue<bool?>(userStatsNode, "authUsers"); 
    var nullableString = AttributeValue<string>(userStatsNode, "authUsers"); 
    var pendingUsersBoolNull = AttributeValue<bool?>(userStatsNode, "pendingUsers"); 
    var testAttribNullableNotFoundDateTime = AttributeValue<DateTime?>(userStatsNode, "testAttrib"); 
    var testAttrib1NullString = AttributeValue<string>(userStatsNode, "testAttrib"); 
    var maxUsersNullInt = AttributeValue<int?>(userStatsNode, "maxUsers"); 

es funktioniert gut für mich. Dank Leute ...

+0

Mir geht es gut mit NULL-Werte jetzt zurück. das sieht nach einer besseren Lösung aus, – Ashish

5

Für 3.4 müssen Sie bool? als Typ für T verwenden, damit Sie null zurückgeben können.

Dann können Sie das Schlüsselwort default für 3.3 und 3.4 (String und Bool?) Verwenden. Gemäß msdn wird null für Referenztypen und den Standardwert für Werttypen (wie int oder bool) zurückgegeben.

Sie können es verwenden, wie

return default(T); 
+0

Die Anforderungen für den 'bool' Fall (3.4) ist, dass es' null' zurückgibt. Dies wird stattdessen "falsch" zurückgeben und wird nicht von dem Fall unterscheidbar sein, in dem kein übereinstimmendes Attribut gefunden wird und der Fall, in dem "falsch" angegeben ist. –

+0

Sie müssen es dann nicht mit 'bool?' Als generisches Argument verwenden und geben in diesem Fall null zurück? Ich meine, wenn T 'bool' können Sie nicht false zurück, so dass Sie verwenden müssen' Bool? '... –

+0

nur zu klären, default (T) für' Bool? 'Kehrt null –

0

Sie benötigen eine erste Code-Set mit bool? nicht bool nennen, weil null kein gültiger Wert für einen Nicht-Nullable-bool ist.

Ihr zweiter Codeblock schlägt fehl, weil Sie nicht string für die generische Art von Nullable<T> verwenden können, als sie einen Wert-Typ erfordert struct und string eine Klasse Referenz-Typ ist.

Sie benötigen Ihre erste Methode Block suchen typeof(bool?) und nennen Sie es mit einem Nullable-Typ boolean ändern:

public T AttributeValue<T>(XmlNode node, string attributeName) 
{ 
    var value = new object(); 

    if (node.Attributes[attributeName] != null && !string.IsNullOrEmpty(node.Attributes[attributeName].Value)) 
    { 
     value = node.Attributes[attributeName].Value; 
    } 
    else 
    { 
     if (typeof(T) == typeof(int)) 
      value = -1; 
     else if (typeof(T) == typeof(DateTime)) 
      value = DateTime.MinValue; 
     else if (typeof(T) == typeof(string)) 
      value = null; 
     else if (typeof(T) == typeof(bool?)) 
      value = null; 
    } 

    var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); 
    return (T)Convert.ChangeType(value, type); 
} 

Dann ist es so nennen:

bool? value = AttributeValue<bool?>(node, "myAttributeName"); 

Sie müssen auch Führen Sie eine Überprüfung durch, da Convert.ChangeType für einen Nullable-Typ nicht funktioniert. Eine schnelle Lösung von here löst das.(Es ist im Code enthalten oben)

EDIT: Hier ist eine verbesserte/gereinigte Version Ihrer Methode:

public T AttributeValue<T>(XmlNode node, string attributeName) 
{ 
    if (node.Attributes[attributeName] != null && !string.IsNullOrEmpty(node.Attributes[attributeName].Value)) 
    { 
     var value = node.Attributes[attributeName].Value; 
     var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); 
     return (T)Convert.ChangeType(value, type); 
    } 
    else 
    { 
     if (typeof(T) == typeof(int)) 
      return (T)(object)(-1); 

     return default(T); 
    } 
} 

Sie zusätzliche Sonderfälle für nicht vorhandene Knoten hinzufügen können, aber alle Fälle mit Ausnahme int sind bereits die Standardwerte für die Typen. Verwenden Sie stattdessen einfach .