Returns null for an unknown type

I am trying to write the following method using generics. (My actual method is more complicated than this.)

public T ParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary) { T result; if (dictionary.TryGetValue(s, out result)) return result; // TODO: Return special value such as null to indicate invalid item } 

My goal is to return something like null if the item is not in the dictionary.

The problem is that I do not know what type T . If T was an integer, for example, then should I return a type T? . However, if T is a class, then it is already NULL. And I will not know this until runtime.

Can someone see a clean way to return a special value in this method to indicate that an element is invalid? I am open to returning anything other than null , but this should be of special significance. (0 is not a special value for integers.)

+5
source share
4 answers

I would suggest returning ParseResult<T> , which is defined as something like:

 public struct ParseResult<T> { // Or an exception, or a way of creating an exception private readonly bool success; private readonly T value; // Accessors etc } 

Thus, you do not need to worry about zero tolerance, and you can very clearly understand what you are doing. This is the template that I used in Noda Time , and in my opinion, it worked very well. (We are currently using a class, not a structure, but I can change this ...)

I prefer it to other approaches, because:

  • Pure to call, as opposed to using the out parameter
  • No ugly and potentially expensive try / catch processing is required.
  • It behaves exactly the same whether T reference type or a value type
  • It is flexible enough to represent a situation where null is a successful parsing value.
  • You can still propagate the cause of the failure without causing an exception when you don't need
+10
source

Perhaps two overloads will help:

 public T? ParseStructDictionaryItem<T>(string s, Dictionary<string, T> dictionary) where T : struct { T result; if (dictionary.TryGetValue(s, out result)) return result; return null; } public T ParseReferenceDictionaryItem<T>(string s, Dictionary<string, T> dictionary) where T : class { T result; if (dictionary.TryGetValue(s, out result)) return result; return default(T); } 
+5
source

You can create two methods: one for value types and one for a reference type. A value type method returns T? instead of T . In both methods, you can return null to indicate an invalid value.

 public T? ParseDictionaryItemValueType<T>(string s, Dictionary<string, T> dictionary) where T : struct { T result; if (dictionary.TryGetValue(s, out result)) return result; return null; } public T ParseDictionaryItemReferenceType<T>(string s, Dictionary<string, T> dictionary) where T : class { T result; dictionary.TryGetValue(s, out result); return result; } 
+4
source

Why reinvent the wheel? Take a look at your own code:
You are using the Dictionary method TryGetValue . How does he deal with the same problem?
I suggest you follow in the footsteps of the .Net Framework developers and do the same:

 public bool TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out T result) { if (dictionary.TryGetValue(s, out result)) { return true; } return false; 

}

Update
Since you don't like this approach, how about including it?

 public T TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out bool Success) { T result = default(T); Success = (dictionary.TryGetValue(s, out result)) return result; } 
0
source

All Articles