我可以对这样的代码使用模式匹配吗(在泛型上)
Can I use pattern matching for code like this (on generic types)
我想使用模式匹配来替换多个 if
语句,如下面的方法 Select<T>()
所示。我想在 typeof(T)
.
上使用 switch()
语句
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#
暂时还做不到(建议here and here)。
但是有一个 hack,如 中所示,虽然不是完全相同的。
我可以使用的解决方案如下(感谢@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
语句序列的改进。
我想使用模式匹配来替换多个 if
语句,如下面的方法 Select<T>()
所示。我想在 typeof(T)
.
switch()
语句
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#
暂时还做不到(建议here and here)。
但是有一个 hack,如
我可以使用的解决方案如下(感谢@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
语句序列的改进。