Need to call your first code with bool? not bool because null not a valid value for a non-nullable bool .
The second code block does not work because you cannot use string for the general type Nullable<T> , since it requires a value type of struct and string .
You will need to change your first method block to look for typeof(bool?) And call it using a type with a zero Boolean type:
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); }
Then name it like:
bool? value = AttributeValue<bool?>(node, "myAttributeName");
You also need to do a check since Convert.ChangeType will not work for a type with a null value. A quick fix from here resolves this. (it is included in the code above)
EDIT: here's the improved / cleaned version of your method:
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); } }
You can add additional special cases for nonexistent nodes, but all your cases except int are already the default value for types, so just use default(T) .
source share