C# 泛型效率,一种更好的方法
好的,假设我有如下类:
public class KPIObject<T> //<--This class where T is the following classes
{
public List<T> Data { get; set; }
public string Caption { get; set; }
}
public class KPICycleCountAccuracyData //<--There are 20 of these with different names and values
{
public string Facility { get; set; }
public string CCAdjustedCases { get; set; }
public string TotalCases { get; set; }
public string CCAdjustedPercent { get; set; }
}
然后我有:
public List<ReportData>> ProcessAccountReport(GetAccountReport request)
{
var data = new List<ReportData>();
ProcessKPI(data, request.KPICycleCountAccuracy, "KPICycleCountAccuracy"); //<-- 20 of these
return data;
}
这是 ProcessKPI 方法:
private static void ProcessKPI<T>(List<ReportData> data, ICollection<KPIObject<T>> items, string name)
{
if (items == null || items.Count <= 0) return;
foreach (var item in items)
{
if (item.Data == null || item.Data.Count <= 0) continue;
var temp = new List<object>();
temp.AddRange((IEnumerable<object>)item.Data);
data.Add(new ReportData { Data = temp, Name = name, Title = item.Caption });
}
}
所有这些都可以正常工作并编译,我只是想知道这是否是最有效的方法。
谢谢。
编辑
我将流程 KPI 更改为:
private static void ProcessKPI<T>(ICollection<ReportData> data, ICollection<KPIObject<T>> items, string name)
{
if (items == null || items.Count <= 0) return;
foreach (var item in items.Where(item => item.Data != null && item.Data.Count > 0))
{
data.Add(new ReportData { Data = (IEnumerable<object>)item.Data, Name = name, Title = item.Caption });
}
}
Ok, lets say I have classes such as the following:
public class KPIObject<T> //<--This class where T is the following classes
{
public List<T> Data { get; set; }
public string Caption { get; set; }
}
public class KPICycleCountAccuracyData //<--There are 20 of these with different names and values
{
public string Facility { get; set; }
public string CCAdjustedCases { get; set; }
public string TotalCases { get; set; }
public string CCAdjustedPercent { get; set; }
}
Then I have:
public List<ReportData>> ProcessAccountReport(GetAccountReport request)
{
var data = new List<ReportData>();
ProcessKPI(data, request.KPICycleCountAccuracy, "KPICycleCountAccuracy"); //<-- 20 of these
return data;
}
Here is the ProcessKPI method:
private static void ProcessKPI<T>(List<ReportData> data, ICollection<KPIObject<T>> items, string name)
{
if (items == null || items.Count <= 0) return;
foreach (var item in items)
{
if (item.Data == null || item.Data.Count <= 0) continue;
var temp = new List<object>();
temp.AddRange((IEnumerable<object>)item.Data);
data.Add(new ReportData { Data = temp, Name = name, Title = item.Caption });
}
}
All of this works and compiles correctly, I am just wondering if this is the most efficient way of doing this.
Thanks.
EDIT
I changed process KPI to this:
private static void ProcessKPI<T>(ICollection<ReportData> data, ICollection<KPIObject<T>> items, string name)
{
if (items == null || items.Count <= 0) return;
foreach (var item in items.Where(item => item.Data != null && item.Data.Count > 0))
{
data.Add(new ReportData { Data = (IEnumerable<object>)item.Data, Name = name, Title = item.Caption });
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
注释
ProcessKPI
中将data
设为ref
参数。如果您实际分配给 C# 中的class
类型,ref
参数仅对它有意义。在这里,您只是修改对象,因此除了尴尬的调用语法之外,ref
不会对您进行任何操作。Count
已签名,它也不会返回负值。(IEnumerable
Couple of comments
data
aref
parameter inProcessKPI
. Aref
parameter is only meaningful for aclass
type in C# if you actually assign to it. Here you're just modifying the object soref
doesn't by you anything except awkward call syntaxCount
is signed it won't ever return a negative value.(IEnumerable<object>)item.Data
over theas IEnumerable<object>
version. If the latter fails it will result in anArgumentNullException
when really it's a casting issue.速度
假设您正在谈论计算效率(即速度),您可能可以改进两个操作:
首先,您在
temp
中创建item.Data
的副本代码>变量。当您知道生成的ReportData
永远不会被修改时,您可以直接使用 item.Data,从而放弃昂贵的复制操作。<代码>)item.Data,
data.Add(新的报表数据{
数据 = (IEnumerable
名字=名字,
Title = item.Caption });
其次,转换为
IEnumerable可能会导致稍后不必要的装箱/拆箱。看看您的应用程序向
ReportData
添加泛型类型参数是否有意义,以便您可以将其实例化为new ReportData()
。这样编译器可以更好地优化代码。内存
通过使用延续来实现您的解决方案,您可以一次处理一个 ReportData 元素,而不是一次处理所有元素,从而减少内存占用。查看
yield
语句看看如何实施这种方法。其他
对于进一步提高代码质量,JaredPar 的回答提供了一些很好的建议。
Speed
Assuming you are talking about computational efficiency (i.e. speed), there are two operations that you might be able to improve:
First, you create a copy of the
item.Data
in thetemp
variable. When you know that the resultingReportData
will never be modified, you may use the item.Data directly, forgoing the expensive copy operation.data.Add(new ReportData {
Data = (IEnumerable<object>)item.Data,
Name = name,
Title = item.Caption });
Second, converting to
IEnumerable<object>
will probably cause unnecessary boxing/unboxing at a later point. See if it makes sense for your application to add a generic type parameter toReportData
, so you may instantiate it asnew ReportData<KPIObject>()
. That way the compiler may do a better job of optimizing the code.Memory
By implementing your solution using continuations you may be able to process one ReportData element at a time instead of all at once, thereby reducing the memory footprint. Have a look at the
yield
statement to see how to impelement such an approach.Other
For futher code quality improvements, JaredPar's answer offers some exellent advice.