c# - 我可以对这样的代码使用模式匹配吗(在泛型上)
问题描述
我想使用模式匹配来替换多个if
语句,如下所示的方法Select<T>()
。我想switch()
在typeof(T)
.
static class Program
{
static void Main(string[] args)
{
var doc = new Document();
IWire select = doc.Select<IWire>();
}
public static T Select<T>(this Document document) where T : class, IGeneric
{
var t = typeof(T);
if (t.IsAssignableTo(typeof(IWire)))
{
return document.SelectEntity(EntityType.Wire) as T;
}
if (t.IsAssignableTo(typeof(ISolid)))
{
return document.SelectEntity(EntityType.Solid) as T;
}
if (t.IsAssignableTo(typeof(ISurface)))
{
return document.SelectEntity(EntityType.Surface) as T;
}
// imagine a lot of if statements here
return null;
}
}
public enum EntityType
{
Wire,
Surface,
Solid
}
public interface IGeneric
{
}
public interface IWire : IGeneric
{
}
public interface ISurface : IGeneric
{
}
public interface ISolid : IGeneric
{
}
public class Document
{
public IGeneric SelectEntity(EntityType entity)
{
throw new NotImplementedException();
}
}
我见过的所有例子都在语句中使用了一个实例switch(thing)
,下面这样的代码显然是错误的
switch(typeof(T))
{
case // what here?
}
解决方案
因此,基于评论的答案是目前C#
还不能这样做(在此处和此处提出)。
但是有一个 hack,在 https://stackoverflow.com/a/46769048/380384 中有说明,尽管不是完全相同的副本。
我可以使用的解决方案如下(感谢@dbc 为我指明了正确的方向)。
public static T Select<T>(this Document document) where T : class, IGeneric
{
var t = typeof(T);
switch (true)
{
case var _ when t.IsAssignableFrom(typeof(IWire)):
return document.SelectEntity(EntityType.Wire) as T;
case var _ when t.IsAssignableFrom(typeof(ISurface)):
return document.SelectEntity(EntityType.Surface) as T;
case var _ when t.IsAssignableFrom(typeof(ISolid)):
return document.SelectEntity(EntityType.Solid) as T;
default:
return null;
}
}
但就可读性和设计意图而言,它可能确实是对if
语句顺序的改进。
推荐阅读
- linux - 如何修复 Nessus 扫描报告“缺少功能级别访问控制”?
- python - 在 pycharm 上激活现有的 venv
- excel - 按名称查找列标题,然后从多个工作簿中选择标题下方的所有数据,然后将数据粘贴到 Excel VBA 的主文件中的另一个下方
- javascript - 基本相同的代码,但一个导致无限循环的使用效果
- php - Laravel 8 UniSharp File Manager 3 将基本目录从 app/storage 更改为 app/public
- string - Android:使用字符串 ID 调用字符串资源
- firebase - 在我停止并以调试模式重新运行应用程序后,Flutter 会清除移动应用程序目录(不是临时目录)
- css - 如何垂直对齐较小的材质浮动按钮?
- c# - WriteFile 返回 0 作为字节数
- java - 如何从 api 获取数据并将数据插入 Android Studio 中的 ROOM(数据库)?