我需要在同一个泛型中使用两个版本的基类型:可为空和不可为空。 像整数?和 int,Guid?和GuidOnly?和 DateOnly 等等。 可空类型应该位于类属性中,不可空类型应该位于类字典的键中。并且应该使用 nullable 来搜索该字典。
示例:
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);
}
}
我也尝试仅使用 1 个通用参数,但收到警告
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);
}
}
好的,我正在添加约束,但又收到另一个警告:
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);
}
}
是否可以在没有错误和警告的情况下实现这一目标?
我不完全确定这是否是您想要的,但是:如果您想始终使用类型
T?
作为键,使用 T
作为值,您可以避免指定两个类型参数,例如所以:
class GenericTest<TK> where TK: struct
{
public TK? Key { get; init; }
public Dictionary<TK?, TK> Values { get; set; } = new();
public TK FindValue()
{
if (Key == null)
return default;
return Values.GetValueOrDefault(Key, default);
}
}
这适用于任何结构类型,当然包括
int
、Guid
和 DateOnly
。
您的示例将看起来更像这样:
static void Main()
{
var t = new GenericTest<int>
{
Key = 1
};
t.Values.Add(1, 2);
Console.WriteLine(t.FindValue());
}