How to Return Null from a Generic Method in C#

How can I return NULL from a generic method in C#?

Three options:

  • Return default (or default(T) for older versions of C#) which means you'll return null if T is a reference type (or a nullable value type), 0 for int, '\0' for char, etc. (Default values table (C# Reference))
  • If you're happy to restrict T to be a reference type with the where T : class constraint and then return null as normal
  • If you're happy to restrict T to be a non-nullable value type with the where T : struct constraint, then again you can return null as normal from a method with a return value of T? - note that this is not returning a null reference, but the null value of the nullable value type.

Return null from generic method

default(T) works in both cases.

How do you properly return `null` from a generic marked with [return:MaybeNull]?

Ok, so unfortunately, thanks to the difference between a nullable reference type and a nullable value type--a limitation that something like Swift doesn't have--what I'm after is not supported by C#.

Instead, as mentioned in my other answer, because of this you shouldn't use the 'returning null means no match' pattern. Instead, you should use a try-based pattern that returns a boolean and utilizes an out parameter for the value of interest (if any). Inside, you still use default (so you don't have to constrain T) but you have that extra boolean telling you whether the default itself should be ignored or not. This way will properly work for both class and struct types, and more importantly, for types such as int where the default is not null, but rather zero, it will help you differentiate between a predicate indicating it matched zero (return = true) or there was no passing predicate (return = false) and you can ignore that zero.

The trick is in using the NotNullWhen attribute to tell callers that the out parameter will never be null when the return value of the function is true, so as long as you check the return value before accessing the out parameter, you don't also have to check for null, and code-flow analysis will not display 'possible null' warnings either.

Here's the refactor of the above function...

public static bool TryFind<T>(this IEnumerable<T> items, Func<T, bool> predicate, [NotNullWhen(true)] out T result){

foreach(var item in items){
if(predicate(item)){
result = item;
return true;
}
}

result = default;
return false;
}

Time to go refactor some old code!

Returning nullable and null in single C# generic method?

Not precisely what you want, but a possible workaround would be to return a Tuple (or other wrapper class):

    static Tuple<T> SafeGetObj<T>(List<T> list, int index) 
{
if (list == null || index < 0 || index >= list.Count)
{
return null;
}

return Tuple.Create(list[index]);
}

Null would always mean that no value could be obtained, the single tuple itself would mean a value (even if the value itself can be null).

In vs2015 you could use the ?. notation when calling: var val = SafeGetObj(somedoublelist, 0)?.Item1;
Of course instead of a Tuple, you could create your own generic wrapper.

As stated, not exactly optimal, but it would be a workable work around, and have the added benefit of being able to see the difference between not a valid selection and a null element.


Example of a custom wrapper implementation:

    struct IndexValue<T>
{
T value;
public bool Succes;
public T Value
{
get
{
if (Succes) return value;
throw new Exception("Value could not be obtained");
}
}

public IndexValue(T Value)
{
Succes = true;
value = Value;
}

public static implicit operator T(IndexValue<T> v) { return v.Value; }
}

static IndexValue<T> SafeGetObj<T>(List<T> list, int index)
{
if (list == null || index < 0 || index >= list.Count)
{
return new IndexValue<T>();
}

return new IndexValue<T>(list[index]);
}

How to make a generic method allow returning null and accept enum?

Return a nullable instead of a plain T:

public static T? GetSelectedValue<T>(this ComboBox control) where T : struct
{
if (control.SelectedValue == null)
return null;

return (T)control.SelectedValue;
}

Returning null T

Null may not be a viable value for T if the type passed in is a struct.

You can instead return the default type for T which for a reference type is null:

else
{
log.Error("Error accessing API.");
return default(T);
}

As noted in the below comment, you can alternatively return null if you restrict T to class.

public T GetFromApi<T>(string apiRequest, string content) where T : class
...
else
{
log.Error("Error accessing API.");
return null;
}

However, in the case where you DO need to potentially retrieve primitive types (bool, int, etc), you would no longer be able to consume this method.

Returning null value from generic method

You could return default(K), and that means you will return null if K is a reference type, or 0 for int, '\0' for char, and so on...

Then you can easily verify if that was returned:

if (object.Equals(resultValue, default(K)))
{
//...
}

Generic method to return Nullable Type values

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...

Returning null for generic type extension in c#

Then just return default value

//Check for empty or null first
if(string.IsNullOrEmpty(value)) return default(T);

//Then your code
var stringType = "System.Nullable`1[[System.{0}, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]";
...

How do I return null from generic function?

You can add a generic constraint that T is a class (as structures are value types and cannot be null).

private T DeserializeStream<T>(Stream data) where T : class, IExtensible

As @mindandmedia commented, an alternative is to return the default of T - this will allow it to work on value types (such a Nullable<T>, int32 etc...).



Related Topics



Leave a reply



Submit