Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method to return Nullable Type values

I wrote below method with follwing requirement -

  1. input is xmlnode and attributeName
  2. return the value if it is found with the associated attribute name passed
  3. Where there is no value in attributeName being passed, it should return -

    3.1. For int -1 3.2. For Datetime DateTime.MinValue 3.3. For String, null 3.4. For bool, null

Below method fails for case 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));
        }

When change this to

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));
        }

It fails for string type i.e. case 3.3

Looking forward for some help.

like image 934
CuriousBenjamin Avatar asked Jun 28 '13 11:06

CuriousBenjamin


1 Answers

thanks for a number of replies, this is what I wrote and it works for me..

It returns null for the types.

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);
        }

I call it like this

    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");

it works well for me. thanks people...

like image 81
CuriousBenjamin Avatar answered Oct 13 '22 23:10

CuriousBenjamin