I need to use two versions of base type in the same generic: nullable and non-nullable. Like int? and int, Guid? and Guid, DateOnly? and DateOnly and so on. Nullable type should be at the class property, non-nullable should be at class dictionary's key. And nullable should be used to search on that dictionary.
Example:
var t = new GenericTest<int?, int> # ERROR: The type 'int?' must be convertible to 'int' in order to use it as parameter 'TK' in the generic class 'GenericTest<TK,TV>'
{
Key = null
};
t.Values.Add(1, 2);
Console.WriteLine(t.FindValue());
class GenericTest<TK, TV>
where TK: TV
where TV : notnull
{
public TK? Key { get; set; }
public Dictionary<TV, int> Values { get; set; } = new();
public int FindValue()
{
if (Key == null)
return 0;
return Values.GetValueOrDefault(Key, 0);
}
}
I also tried to use only 1 generic parameter, but got warning
var t = new GenericTest<int?>
{
Key = null
};
t.Values.Add(1, 3);
Console.WriteLine(t.FindValue());
class GenericTest<TK>
{
public TK? Key { get; set; }
public Dictionary<TK, int> Values { get; set; } = new(); # WARNING: Nullability of type argument 'TK' must match 'notnull' constraint in order to use it as parameter 'TKey'
public int FindValue()
{
if (Key == null)
return 0;
return Values.GetValueOrDefault(Key, 0);
}
}
Ok, I'm adding constraint, but getting another warning:
var t = new GenericTest<int?> # WARNING: Nullability of type argument 'int?' must match 'notnull' constraint in order to use it as parameter 'TK'
{
Key = null
};
t.Values.Add(1, 3);
Console.WriteLine(t.FindValue());
class GenericTest<TK> where TK : notnull # ADDED HERE
{
public TK? Key { get; set; }
public Dictionary<TK, int> Values { get; set; } = new();
public int FindValue()
{
if (Key == null)
return 0;
return Values.GetValueOrDefault(Key, 0);
}
}
Is it possible to achieve that without errors and warnings?