繁体   English   中英

C#:如何在另一个类中使用可索引属性?

[英]C#: How to use indexable properties inside another class?

我正在从视图中读取数据到列表中的项目。 每个项目都是一个字符串和三个双打:

public class StatReportDataItems
{
    public string Label { get; set; }

    public double NumData1 { get; set; }

    public double NumData2 { get; set; }

    public double NumData3 { get; set; }
}

这是包含该列表的类:

public class StatReportDataModel
{
    public string SReportType { get; set; }

    public int numdatas { get; set; }

    public List<StatReportDataItems> StatReportDataList { get; set; }

    public string ReportTitle { get; set; }

}

读取数据到列表的许多例程之一:

    public List<StatReportDataItems> GetReport888()
    {
        var query = from rv in ProcessDB.Report888Views
                    select new StatReportDataItems
                    {
                        Label = rv.Label,
                        NumData1 = (double)rv.NumData1
                    };
        var retValue = query.ToList();
        return retValue;
    } // GetReport888

一些例程还将数据填充到NumData2和Numdata3中,然后有一个常规例程使用chart.js显示数据。

最初它只是“显示”,但是现在在常规显示例程获取数据之前,应该对数据做越来越多的事情。 由于这包括循环遍历数据,如果三个Numdata改为具有三个项的数组/列表/集合(将来可能还会更多),它将使代码变得更好。

由于返回数组被视为一个很大的禁忌,所以我认为我应该使用索引属性。 这将是一个开始:

public class Constants
{
    public static int AntalData = 3;
}

public class NumDataType
{
    private double[] numarr = new double[Constants.AntalData];
    public int Length
    {
        get { return numarr.Length; }
    }
    public double this[int index]
    {
        get { return numarr[index]; }
        set { numarr[index] = value; }
    }
}

直接在我的应用程序中使用此NumDataType很容易:

NumDataType NumItems = new NumDataType();
NumItems[0] = 3.14;

但是,当我尝试在类StatReportDataItems中使用它,然后替换

NumData1 = (double)rv.NumData1

在GetReport888中,尝试使用不同的代码编写方式,无法正常工作。 大多数情况下,我会收到编译器错误“当前上下文中不存在名称'NumData'”

带有更改的NumData的StatReportDataItems类:

public class StatReportDataItems
{
    public string Label { get; set; }

    public NumDataType NumData { get; } = new NumDataType();

}

那么,我在做什么错呢? 也许现在是我该回家的时候了,明天我会看得更清楚,但我认为有些帮助是一个更安全的选择。

由于一些评论者似乎在阅读我写的内容时遇到问题,因此我尝试在此处进行澄清:

  • StatReportDataModel类的对象传递给呈现常规例程的常规图表(敲除javascript中的代码,调用chart.js)。
  • List StatReportDataList填充了StatReportDataItems类的对象,此数据是从DB视图读取的。
  • 例程GetReport888是负责获取数据的许多小例程之一,通常每个例程获取一个报告。 每个项目仅返回一个数值数据,其他返回两个或三个。

一切正常,但我可以看到将Numdata1-Numdata3更改为具有三个项目的NumData []可以简化常规js代码。 所以我认为我应该做这个看似简单的更改。 只是在两个地方...

因此,我创建了NumDataType并将StatReportDataItems中的三个double属性替换为该类型的一个属性。 然后我将GetReport888更改为:

    public List<StatReportDataItems> GetReport888()
    {
        var query = from rv in ProcessDB.Report888Views
                    select new StatReportDataItems
                    {
                        Label = rv.Label,
                        NumData[0] = (double)rv.NumData1
                    };
        var retValue = query.ToList();
        return retValue;
    } // GetReport888

如果我做错了什么,我准备得到类型为“无法隐式转换...”的错误消息,而不是“当前上下文中不存在名称'NumData'” ...

这是从数据库视图生成的Report888View类:

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Report888View")]
public partial class Report888View
{   
    private string _Label;      
    private System.Nullable<double> _NumData1;      
    public Report888View()
    {
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Label", DbType="VarChar(100)")]
    public string Label
    {
        get
        {
            return this._Label;
        }
        set
        {
            if ((this._Label != value))
            {
                this._Label = value;
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_NumData1", DbType="Float")]
    public System.Nullable<double> NumData1
    {
        get
        {
            return this._NumData1;
        }
        set
        {
            if ((this._NumData1 != value))
            {
                this._NumData1 = value;
            }
        }
    }
}

那么,为什么会出现此特定错误?

编辑:在@howcheng的帮助下,我有最终的GetReport888:

public List<StatReportDataItems> GetReport888()
{
    List<StatReportDataItems> retValue = new List<StatReportDataItems>(); 
    fullmaktnodenProcessDB.Report888Views.ToList().ForEach(rv =>
    { 
        StatReportDataItems data = new StatReportDataItems
        {
            Label = rv.Label,
            NumData = new List<double> {
                (double)(rv.NumData1 == null ? 0.0 : rv.NumData1)
            },
        };
        retValue.Add(data);
    });
    return retValue;
}

之所以得到“名称'NumData'在当前上下文中不存在”的原因是,当您使用对象初始化来填充对象时,只能使用属性设置器,并且NumData属性为只读。 但是即使您将其设置为可设置的,您仍然将无法直接使用索引器,因为您只能设置属性本身。

(注意:您可以在初始化程序中使用索引器,但前提是该索引器位于对象本身上(即this[int index] )。请参见https://docs.microsoft.com/zh-cn/dotnet/csharp/编程指南/类和结构/如何通过使用对象初始化程序初始化对象 。)

同时,假设您必须使用Report888View类,以及我上面关于使用IEnumerable<double>注释,那么这将起作用:

public class StatReportDataItems
{
    public StatReportDataItems()
    {
        NumData = new List<double>();
    }

    public string Label { get; set; }

    public IEnumerable<double> NumData { get; set; }
}

public List<StatReportDataItems> GetReport888()
{
    var query = from rv in ProcessDB.Report888Views
                select new StatReportDataItems
                {
                    Label = rv.Label,
                    NumData = new List<double> { rv.NumData1, rv.NumData2, rv.NumData3 },
                };
    var retValue = query.ToList();
    return retValue;
} // GetReport888

小提琴: https : //dotnetfiddle.net/q84TwK

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM