当我试图使这段代码证明错误时,我将从强制转换中获得多少性能损失?
本文关键字:转换 损失 性能 多少 段代码 错误 证明 代码 | 更新日期: 2023-09-27 18:11:06
我有以下代码:
public class CrudModel<T> : ICrudModel<T> where T : DomainBase
{
public IQueryable<T> GetAll()
{
return Repository.Query<T>();
}
}
问题是,一些对象(T)我需要做一个额外的过滤器,所以我创建了一个单独的方法,像这样:
public IEnumerable<TR> GetAllwithinOrg<TR>() where TR : DomainBase, IFilterable
{
var items = Repository.Query<TR>();
return FilterwithinOrg(items);
}
,其中过滤器方法看起来像这样:
public IEnumerable<TResult> FilterwithinOrg<TResult>(IEnumerable<TResult> linked) where TResult : IFilterable
{
var dict = GetDict();
return linked.Where(r => dict.ContainsKey(r.Id));
}
这一切都很好,但问题是,我必须记住调用方法1或方法2(基于对象是否支持IFilterable
接口
public IQueryable<T> GetAll()
{
var items = Repository.Query<T>();
if (typeof(IFilterable).IsAssignableFrom(typeof(T)))
{
items = FilterwithinOrg(items.Cast<IFilterable>()).Cast<T>().AsQueryable();
}
return items;
}
所以我可以在一个方法中支持两个用例。这似乎是有效的,但我试图理解我将采取什么类型的性能打击通过执行这个
items.Cast<IFilterable>()).Cast<T>().AsQueryable()
如果它很糟糕,那么我将处理记住从外部调用两个单独的方法,但显然只有一个方法会很方便。有什么建议吗?
我想如果我忘记调用第二个方法,我会把它作为备份,但是我想再看看我是否可以只保留一个方法,如果可能的话,让外部调用者更简单。
在CrudModel类中使用where子句的另一个方法如何?
public IEnumerable<T> GetAll<T>(Func<T, bool> whereClause) where T : DomainBase
{
var items = Repository.Query<T>();
return items.Where(whereClause);
}
和调用
List<int> intList = new List<int>() { 1 };
intList.GetAll<int>((i) => sampledict.ContainsKey(i));
我觉得把逻辑挤进一个单一的GetAll方法使事情变得复杂是不合适的,因为CrudModel似乎是通用的,最好有接受任何条件的通用方法。
首先,我认为你有一个函数GetAll有点奇怪,但是对于某些类型,你开始过滤,导致没有得到全部:)
除此之外,我不认为你有很大的性能损失…实际上你在你的GetAll
里面做了一个额外的检查——方法:typeof(IFilterable).IsAssignableFrom(typeof(T))
就像一个普通的cast。你几乎感觉不到。
也许过滤器本身可以改进。创建一个字典。字典是否每次调用都有相同的值,或者是否会改变。如果只使用键而不使用值,为什么要使用字典呢?那HashSet<T>
呢
与数据库查询所花费的时间相比,可以忽略类型转换时间。但是,您是根据下面的代码在内存中查询整个表和过滤器:
public IEnumerable<TResult> FilterwithinOrg<TResult>(IEnumerable<TResult> linked) where TResult : IFilterable
{
var dict = GetDict();
return linked.Where(r => dict.ContainsKey(r.Id));
}
请记住,您需要过滤查询,而不是列表,因此您应该更改方法以接受并返回IQueryable<TResult>
,如:
public IQueryable<TResult> FilterwithinOrg<TResult>(IQueryable<TResult> linked) where TResult : IFilterable
{
var dictKeys = GetDict().Keys.ToList();
return linked.Where(r => dictKeys.Contains(r.Id));
}
请注意,过滤器表达式必须具有等效的SQL表达式,否则将发生运行时错误。