C# 泛型效率,一种更好的方法

发布于 2024-10-30 19:23:16 字数 1939 浏览 0 评论 0原文

好的,假设我有如下类:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

卖梦商人 2024-11-06 19:23:16

注释

  • 无需在 ProcessKPI 中将 data 设为 ref 参数。如果您实际分配给 C# 中的 class 类型,ref 参数仅对它有意义。在这里,您只是修改对象,因此除了尴尬的调用语法之外, ref 不会对您进行任何操作。
  • 即使 Count 已签名,它也不会返回负值。
  • 我更喜欢 (IEnumerable)item.Data 而不是 as IEnumerable版本。如果后者失败,则会导致 ArgumentNullException,而实际上这是一个强制转换问题。

Couple of comments

  • There is no need to make data a ref parameter in ProcessKPI. A ref parameter is only meaningful for a class type in C# if you actually assign to it. Here you're just modifying the object so ref doesn't by you anything except awkward call syntax
  • Even though Count is signed it won't ever return a negative value.
  • I would prefer (IEnumerable<object>)item.Data over the as IEnumerable<object> version. If the latter fails it will result in an ArgumentNullException when really it's a casting issue.
坏尐絯 2024-11-06 19:23:16

速度
假设您正在谈论计算效率(即速度),您可能可以改进两个操作:

首先,您在 temp 中创建 item.Data 的副本代码>变量。当您知道生成的 ReportData 永远不会被修改时,您可以直接使用 item.Data,从而放弃昂贵的复制操作。

<代码>
data.Add(新的报表数据{
数据 = (IEnumerable)item.Data,
名字=名字,
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 the temp variable. When you know that the resulting ReportData 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 to ReportData, so you may instantiate it as new 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文