C# 在C中查找包含类型和操作的表
我想把我的许多if改成一个查找表 我有类型和方法。我想把它们配对C# 在C中查找包含类型和操作的表,c#,dictionary,methods,types,lookup-tables,C#,Dictionary,Methods,Types,Lookup Tables,我想把我的许多if改成一个查找表 我有类型和方法。我想把它们配对 if (propertyType == typeof(bool) || propertyType == typeof(bool?)) DoBool(propertyType); if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?)) DoDateTime(propertyType); if (propertyType == typeo
if (propertyType == typeof(bool) || propertyType == typeof(bool?))
DoBool(propertyType);
if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?))
DoDateTime(propertyType);
if (propertyType == typeof(Guid) || propertyType == typeof(Guid?))
DoGuid(propertyType);
我必须编一本字典吗?或者哪种方式最优雅
你能给我一些建议我从哪里开始或者在哪里可以找到解决方案 您可以创建字典:
您可以创建一个方法来初始化指定类型的查找表,以避免重复
private readonly IDictionary<Type, Action<Type>> _lookup;
因为这更多地是关于控制代码流而不是纯粹的查找,所以我可能会使用面向对象的方法,将每个处理程序的代码放在单独的类中,并将公共内容放在基类中 您可以创建一个公共接口,如
public interface ITypeHandler {
void HandleType(Type type);
}
。。。如果愿意,可以将处理程序的实现放在dictionary类型的dictionary中,或者可以在接口上设置一个属性,显示它处理的类型,并根据该属性从依赖注入处理程序列表中进行选择
这增加了诸如关注点分离、可测试性等好处
请注意,*Handler不是一个很好的名称,您必须根据您正在介绍的场景创建一个更好的名称。我创建了自己的实现,这有点不同,但我使用了@DaggeJ建议,所以谢谢 首先,我创建了一个基本处理程序类。之后,我在不同类型的类上使用了这个基。你可以在下面看到 基类: 后代类: 用法:
您当然可以创建一个字典-这听起来像是您希望从您向我们展示的内容中得到的。@JonSkeet谢谢您,当我创建此字典时,我如何使用它而不是if语句?if myDictionary.TryGetValuemyType,out var action myType;:检查给定类型myType是否有操作,如果有,则执行该操作如果您确信总会有条目,则可以使用dictionary[propertyType].InvokepropertyType。否则,您可能希望使用TryGetValue并仅在存在条目时调用该值。鉴于propertyType无论如何都是键,您可以使用字典,只注册将在必要时传递适当参数的操作。如果不看看你的方法是什么,就很难知道什么是最好的。@JonSkeet谢谢你的回答,你帮了我很多。谢谢Johnny,当我找到的时候,我会混合的,这足以开始我自己的解决方案。
private readonly IDictionary<Type, Action<Type>> _lookup;
private void AddEntry<T>(Action<Type> action) where T : struct
{
_lookup[typeof(T)] = action;
_lookup[typeof(Nullable<T>)] = action;
}
private void DoInt(Type type) { /* implementation */ }
AddEntry<bool>(type => { /* implementation */ });
AddEntry<int>(DoInt);
public interface ITypeHandler {
void HandleType(Type type);
}
public abstract class QueryHandler<T> where T : class
{
//I added here more property.
public abstract Type[] Types { get; }
protected QueryHandler(//Properties)
{
//Properties null check
}
public abstract IQueryable<T> Handle();
}
internal class GuidQuery<T> : QueryHandler<T> where T : class
{
public override Type[] Types => new Type[] { typeof(Guid), typeof(Guid?) };
public GuidQuery(//Properties) : base(//Properties)
{
}
public override IQueryable<T> Handle()
{
// Implementation
}
}
public IQueryable<T> GetQuery()
{
var queryHandlerList = new List<QueryHandler<T>>()
{
new IntQuery<T>(//Properties),
new DateTimeQuery<T>(//Properties),
new StringQuery<T>(//Properties),
new BoolQuery<T>(//Properties),
new GuidQuery<T>(//Properties),
new EnumQuery<T>(//Properties)
};
}
return query = queryHandlerList.FirstOrDefault(h => GetType<T>(h, property.PropertyType)).Handle();
private bool GetType<T>(QueryHandler<T> handler, Type type) where T: class
{
if (handler.Types.FirstOrDefault(t => t == type) == type || handler.Types.FirstOrDefault(t => t == type.BaseType) == type.BaseType) return true;
return false;
}