c# - 使用 Unsafe.As 从标记接口转换为已知的泛型类型?
问题描述
我经常面临需要缓存通用泛型接口的对象但具有不同泛型类型的场景。
让我们考虑这个非常人为的例子(显然不完全是真实世界的用例):
// IInterface is effectively just use as a non-generic marker interface for...
interface IInterface
{ }
// ... This one here!
interface IInterface<T1, T2> : IInterface
{
T1 DoSomething(T2 withB);
}
class TheCache
{
private readonly Dictionary<IInterface, IInterface> _cache = new();
public void Store<T1, T2>(IInterface<T1,T2> key, IInterface<T1, T2> value)
=> _cache[key] = value;
private IInterface<T1, T2> Get<T1, T2>(IInterface<T1, T2> key)
{
// Can we use Unsafe.As safely here?
return Unsafe.As<IInterface<T1, T2>>(_cache[key]);
}
}
TheCache 确保类型一致性;我们知道_cache中的每一个key和value不仅仅是IInterface,实际上是IInterface<,>的一些通用表现。我们也知道 key 和 value 实例的泛型类型是相同的。
现在在 Get 函数中,我们知道检索到的值实际上是一个 IInterface<T1,T2>,但我们仍然需要转换它。一种“幼稚”的方式就是
private IInterface<T1, T2> Get<T1, T2>(IInterface<T1, T2> key)
=> (IInterface<T1,T2>)_cache[key];
虽然效果很好,但我认为进行检查演员表会有(微小的)性能损失。
既然我们知道演员表会成功,我们可以应用任何未经检查的演员表吗?具体来说,
- 我们可以安全地使用 Unsafe.As<IInterface<T1,T2>>() 吗?我对 C# 接口调度不是 100% 坚定的;虽然我们知道结果将是 IInterface<T1,T2>() 的实例,但我不确定 C# 在(安全)将 IInterface 转换为 IInterface<T1,T2> 时是否通常需要进行任何转换,这不会出现不安全的演员表
- 可能不会,但以防万一:如果 _cache 是 Dictionary<object,object> 而不是 Dictionary<IInterface, IInterface>,这个问题的答案会改变吗?
解决方案
推荐阅读
- ffmpeg - FFMEPG 裁剪:对于宽度“1920”或高度“1040”而言,尺寸过大或非正数无效
- sql - 通过 Crystal Reports 在查询中选择计数
- python-3.x - 我的程序没有在 pygames 中输入 if 语句
- unity3d - 如何在 2D 平面上平衡重量
- python - 用python最大化对数似然函数
- html - 如何让悬停下划线出现在文本上方并具有阴影效果?
- vue.js - flatpickr.js 可以在开发中使用,但不能在使用 Vue.js 的生产中使用
- .net - 来自 .NET Windows 服务 .config 文件中的“不那么特殊”字符的错误
- javascript - npm run dev 和 parcel index.html 的区别
- react-native - 如何在展会上更改 MIUI 强制暗模式?