Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字典格式化子列表的访问器是否可能每次都不创建新对象?_C#_Getter - Fatal编程技术网

C# 字典格式化子列表的访问器是否可能每次都不创建新对象?

C# 字典格式化子列表的访问器是否可能每次都不创建新对象?,c#,getter,C#,Getter,首先-是的,我看了这个问题:。 我也不是说在访问器/变体中初始化一个对象,而是指我希望以特定方式返回的对象的特定部分 我的问题比较具体,;它不一定只适用于C#,但是我目前正在寻找一种解决方案,以便在我的C#项目中实现 我有一个带有字典的类,它将日期对象映射为十进制值。在一个访问器中,我想返回字典所有键的列表,另一个访问器返回值。 我还想要一个访问器,它以特定的格式为我提供十进制值。它看起来像这样: class Class { // Some other properties...

首先-是的,我看了这个问题:。 我也不是说在访问器/变体中初始化一个对象,而是指我希望以特定方式返回的对象的特定部分

我的问题比较具体,;它不一定只适用于C#,但是我目前正在寻找一种解决方案,以便在我的C#项目中实现

我有一个带有字典的类,它将日期对象映射为十进制值。在一个访问器中,我想返回字典所有键的列表,另一个访问器返回值。 我还想要一个访问器,它以特定的格式为我提供十进制值。它看起来像这样:

class Class
{
    // Some other properties...
    // ....

    private Dictionary<DateTime, decimal> dict;

    public Class(Dictionary<DateTime, decimal> dict)
    {
        this.dict = dict;
    }

    private string FormatTheWayIWant(decimal dt)
    {
        // Format decimal value.
        string s = String.Format("{0:F}", dt);
        return s;
    }

    public ReadOnlyCollection<DateTime> DateTimes
    {
        get { return new ReadOnlyCollection<DateTime>(this.dict.Keys.ToList()); }
    }

    public ReadOnlyCollection<decimal> Values
    {
        get { return new ReadOnlyCollection<decimal>(this.dict.Values.ToList()); }
    }

    public ReadOnlyCollection<string> FormattedStrings
    {
        get
        {
            // Format each decimal value they way I want.
            List<string> list = new List<string>();
            foreach (decimal dt in dict.Keys)
            {
                list.Add(FormatTheWayIWant(dt));
            }
            return new ReadOnlyCollection<string>(list);
        }
    }
}
string formattedS = FormattedStrings[5];
这种方法的问题是,每次调用FormattedStrings访问器时,我都会创建一个新列表,即使我只需要一个格式化字符串。我知道这不是一个好的做法,可能会带来不必要的性能问题

我想到的备选方案是:

  • 我可以扩展
    decimal
    类并实现一个定制的ToString()方法
  • 或者覆盖
    KeyValuePair
    类并在我的类中使用索引器
  • 或者我创建了一个带有索引参数的方法,只返回一个格式化的字符串
  • 或者我可以有一个自己的访问器列表,每次我更新字典时,它都会在我字典的set方法中更新
  • 我的问题是,有没有一种方法可以使用访问器而不是方法,创建自定义类,或者在赋值时对其他对象产生奇怪的副作用


    提前谢谢你。

    这是VB,但你明白了

    Public Class Something
    
      Public Property Items As Dictionary(Of DateTime, String)
    
      Public Readonly Property FormattedItem(ByVal index As Int32) As String
        ' add error checking/handling as appropriate
        Return Me.Items.Keys(index).ToString("custom format")  '  or whatever your formatting function looks like.
      End Property
    End Class
    

    当然,这可以通过访问器来完成。您只需为已处理集合的每个所需元素创建3个单独的类。这些类应该有自己的索引器,这样您就能够以列表的形式访问元素。不同之处在于,他们根据需要计算每个元素(称为wch)。所以它是这样的(您的
    格式化字符串的示例):

    您访问的每个元素都将在访问时进行计算。此解决方案还具有的优点是,如果您必须为3个访问器中的一个实现不同的逻辑,那么只需扩展其中一个索引器即可


    您可以在此处阅读有关索引器的更多信息:

    您的
    日期
    字符串
    属性获取程序将在每次调用时返回一个新列表。因此,如果调用方执行以下操作:

    Class myClass = ...
    for(i=0; i<myClass.Strings.Count; i++)
    {
        var s = myClass.Strings[i];
        ...
    }
    

    它看起来是一个新班级的好候选人

    public class MyObject
    {
        public DateTime Key {get;set;}
        public String Name {get;set;}
        public String FormattedString {get;}
    }
    

    然后它可以在任何容器中使用(
    列表、字典等)。

    谢谢你,我实际上更想寻找一个通用的解决方案,在访问器中获取对象的子对象。这是格式化字符串的一个很好的解决方案,我相信我有一段时间可以利用它。对于你的第一句话,我想在我的情况下使用SortedDictionary会更好,因为我希望字典条目按日期和时间排序。使用我的访问器,我试图只返回那些我真正需要的对象。这意味着,当我在字典中查找特定日期时,我只需访问DateTimes属性b/c,我还不需要知道相应的值。关于您的解决方案的一个问题是,您可以在特定索引处懒洋洋地初始化对象。但一旦初始化,if始终引用同一个对象。如果基础词典发生变化,我需要更新该词典条目的格式化字符串表示形式,你会怎么做?@Yeehaw,如果你想以“懒惰”的方式做事,这包括你为“日期时间”和“值”属性创建的列表,然后,您需要在每次更新字典时重新初始化延迟生成的字段。说清楚一点,我并不推荐这种解决方案。在访问原始值时,最好让调用方调用格式化方法如果我想要所有格式化字符串的集合,我必须访问
    列表
    对象中每个项目的格式化字符串。这不会增加不必要的开销吗?开销不会有任何区别。若您需要FormattedString项的集合,那个么无论如何都要迭代它(无论是否为indexer准备它)。使用OO原则将更加清晰。不必写[int index=1;/*然后应用找到的索引*/FormattedStrings[index],您可以写myObject.FormattedString]。只要问问你的同事什么更清楚,如果理解和使用你的代码所需的时间比花在OO上的生命和公司的钱要长得多的话。我编辑了这个问题,并添加了小数,而不是字符串或字典中的值。这应该会更清楚。谢谢你的回答。实际上,我想保留字典,因为我想访问特定日期的十进制值。我不确定您的解决方案在可维护性方面是否合适,因为日期和十进制值不是直接对应的。对不起,我有点搞砸了。当然,我的字典还在班上。。。我真的很喜欢你的解决方案,它不产生任何开销,并且保持一切整洁。非常感谢。(如果可以,我会投你一票)
    Class myClass = ...
    for(i=0; i<myClass.Strings.Count; i++)
    {
        var s = myClass.Strings[i];
        ...
    }
    
    public class MyFormattingCollection : IList<string>
    {
        private IList<decimal> _values;
        private IList<string> _formattedValues;
    
        public MyFormattingCollection(IList<DateTime> values)
        {
            _values = values;
            _formattedValues = new string[_values.Count];
        }
    
        public string this[int index]
        {
            get
            {
                var result = _formattedValues[index];
                if (result == null)
                {
                    result = FormatTheWayIWant(_values[index]);
                    _formattedValues[index] = result;
                }
                return result;
           }
           set
           {
               // Throw: it's a readonly collection
           }
        }
    
        // Boilerplate implementation of readonly IList<string> ...
    }
    
    public class MyObject
    {
        public DateTime Key {get;set;}
        public String Name {get;set;}
        public String FormattedString {get;}
    }