当限制已经包含接口时,在通用类型限制中使用class子句

IsT*_*man 2 c# generics casting

我想我知道为什么,但是如果有人能启发我为什么,在编写此方法的时候,IStoreable接口是什么,将不胜感激:

public bool TryRetrieveItem<T>(string itemKey, out T item) where T : IStoreable
{
    item = default(T);

    if (this.RetrieveItem(itemKey, out IStoreable retItem))
    {
        item = (retItem as T);
        return true;
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

抱怨这个 item = (retItem as T);

为了解决该问题,我必须class在where子句中添加限制。

由于已经在接口上限制了T,为什么我应该这样做?是否因为接口可以通过非引用类型实现?还是我弄错了细节?

Swe*_*per 5

是否因为接口可以通过非引用类型实现?

是。

as您正在使用的运算符只能执行引用类型转换。它尝试将变量转换为所需的类型。如果失败,则表达式的计算结果为null。它不适用于值类型,因为值类型不能为null

这就是为什么您必须约束T一个班级的原因。

或者,您可以将更as改为强制转换。

item = (T)retItem;
Run Code Online (Sandbox Code Playgroud)

如果这样做,则不需要上的引用类型约束T,但是如果转换失败,它将引发异常。

第三种选择是检查retItem使用模式匹配的类型:

if (retItem is T t) {
    item = t;
}
Run Code Online (Sandbox Code Playgroud)