Почему добавление значений в коллекцию перезаписывает предыдущие элементы и как их упростить? - PullRequest
0 голосов
/ 17 марта 2019

На основе абстрактного класса программы добавляют значения в коллекцию. Проблема 1: При отображении добавленных значений все они перезаписываются с последним добавленным значением. Как побочная проблема, добавление значений кажется утомительным, должен быть лучший способ достигнуть этого.

Просматривая другие ответы, возникают похожие проблемы с использованием статического класса, однако здесь это не так. Я попытался удалить «абстрактный», который не имеет значения в выводе.

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

namespace QuoteCoScMe
{
    class Program
    {
        public abstract class Koers
        {
            public string fonds { get; set; }
            public DateTime datum { get; set; }
            public Double koers { get; set; }
        }
        public class Historical : Koers
        {

        }

        private static void Display(Collection<Historical> cs)
        {
            Console.WriteLine();
            foreach (Historical item in cs)
            {
                Console.WriteLine("{0} {1} {2} ", item.fonds, item.datum.ToString(), item.koers);
            }
        }

        static void Main(string[] args)
        {
            Historical xkoers = new Historical() ;
            Collection<Historical> Historicals = new Collection<Historical>();
            xkoers.fonds = "AL1";
            xkoers.datum = DateTime.Parse("2018-05-08");
            xkoers.koers = 310.1;
            Historicals.Add(xkoers);
            xkoers.fonds = "AL2";
            xkoers.datum = DateTime.Parse("2018-06-08");
            xkoers.koers = 320.1;
            Historicals.Add(xkoers);
            xkoers.fonds = "Some other 3";
            xkoers.datum = DateTime.Parse("2019-06-08");
            xkoers.koers = 20.1;
            Historicals.Add(xkoers);
            Display(Historicals);
            /* Question 2: this is a tedious way of adding, i would want to use xkoers.add("AL2", DateTime.Parse("2018-05-08"), 320); */
            /* Question 1: when displaying the historicals for some reason the whole list contains only the latest added item in the list.
               In de VS debugger is shows that all list items have the same values. 

            Output:
                Some other 3 8/06/2019 0:00:00 20,1
                Some other 3 8/06/2019 0:00:00 20,1
                Some other 3 8/06/2019 0:00:00 20,1
                Press any key to continue . . .
             */

        }
    }

}

Ответы [ 5 ]

1 голос
/ 17 марта 2019

Что касается добавления элементов, вы можете использовать Инициализаторы объектов и инициализаторы коллекций

var Historicals = new Collection<Historical>()
{
   new Historical() { fonds = "AL1", datum = DateTime.Parse("2018-05-08"), koers = 310.1),
   new Historical() { fonds = "AL2", datum = DateTime.Parse("2018-06-08"), koers = 310.1)
};
1 голос
/ 17 марта 2019

У вас есть одно ведро

Historical xkoers = new Historical() ;

, и вы заполняете его 3 раза

Вам необходимо обновлять переменную каждый раз, когда вы добавляете ее

xkoers = new Historical() ;
xkoers.fonds = "AL1";
xkoers.datum = DateTime.Parse("2018-05-08");
xkoers.koers = 310.1;
Historicals.Add(xkoers);

xkoers = new Historical() ;
xkoers.fonds = "AL2;
xkoers.datum = DateTime.Parse("2018-05-08");
xkoers.koers = 310.1;
Historicals.Add(xkoers);

// ect

Что касается второй проблемы, вы можете использовать конструктор

0 голосов
/ 31 марта 2019

Улучшение моего ответа и как предложено, попытайтесь лучше объяснить, что происходит, на основе комментариев ниже (все они действительны).

class Program
{
    public class HistoricValue
    {
        public string Name { get; set; }
        public DateTime Lastdate { get; set; }
        public Double Value { get; set; }
    }
    private static void Display(List<HistoricValue> cs)
    {
        Console.WriteLine();
        foreach (HistoricValue item in cs)
        {
            Console.WriteLine("{0} {1} {2} ", item.Name, item.Lastdate.ToString(), item.Value);
        }
    }
    static void Main(string[] args)
    {
        HistoricValue newValue  = new HistoricValue();
        List<HistoricValue> Historicals = new List<HistoricValue>();
        newValue.Name= "Some name 1";
        newValue.Lastdate = DateTime.Parse("2018-05-08");
        newValue.Value = 310.1;
        Historicals.Add(new HistoricValue () { Name=newValue.Name, Lastdate= newValue.Lastdate, Value = newValue.Value });
        Historicals.Add(newValue);
        Console.WriteLine("Expected output: Twice Some Name 1");
        Display(Historicals);
        newValue.Name = "Some name 2";
        newValue.Lastdate = DateTime.Parse("2018-09-09");
        newValue.Value = 210.1;
        Historicals.Add(new HistoricValue() { Name = newValue.Name, Lastdate = newValue.Lastdate, Value = newValue.Value });
        Historicals.Add(newValue);
        Console.WriteLine("\nExpected output: Twice Some Name 1 and twice somename 2");
        Display(Historicals);
        Console.WriteLine("\nReceived output: once Some name 1 and tree times somename 2");
        Console.WriteLine("\nnewValue get assigned values, what is stored in the list is the pointer to values, so item 2,3,4 will point to the same values in memory.");

        List<HistoricValue> Historicals2 = new List<HistoricValue>();
        Console.WriteLine("\nRCorrect ways to fill the list can be by using a constructor");
        Historicals2.Add(new HistoricValue() { Name = "Some name 1", Lastdate = DateTime.Parse("2018-05-08"), Value = 310.1 });
        Historicals2.Add(new HistoricValue() { Name = "Some name 2", Lastdate = DateTime.Parse("2018-06-08"), Value = 100.1 });
        Console.WriteLine("Expected output: Some Name 1 and Somename 2");
        Display(Historicals2);
        Console.WriteLine("\nOr add with specifically creating a new posistion in the list and add it.");
        newValue.Name = "Some name 3";
        newValue.Lastdate = DateTime.Parse("2018-05-08");
        newValue.Value = 310.1;
        Historicals2.Add(new HistoricValue() { Name = newValue.Name, Lastdate = newValue.Lastdate, Value = newValue.Value });
        newValue.Name = "Some name 4";
        newValue.Lastdate = DateTime.Parse("2018-09-09");
        newValue.Value = 999;
        Historicals2.Add(new HistoricValue() { Name = newValue.Name, Lastdate = newValue.Lastdate, Value = newValue.Value });
        Console.WriteLine("Expected output: Some Name 1,2,3 and 4");
        Display(Historicals2);
        Console.WriteLine("\nOr through using a loop in wich a variable is created and assiged and then stops living.");
        for( int x = 5; x<= 7; x++)
        {
            HistoricValue newValueInLoop = new HistoricValue();
            newValueInLoop.Name = "Some name " + x.ToString();
            newValueInLoop.Lastdate = DateTime.Parse("2018-09-09");
            newValueInLoop.Value = 999+x;
            Historicals2.Add(new HistoricValue() { Name = newValueInLoop.Name, Lastdate = newValueInLoop.Lastdate, Value = newValueInLoop.Value });
            //Display(Historicals2);
        }
        Console.WriteLine("Expected output: Some Name 1,2,3,4,5,6,7");
        Display(Historicals2);
        Console.WriteLine("Actually this is strange, realizing the variable only exists in the loop, yet the memory values are retainted, i hope the garbage collector works");
    }
}
0 голосов
/ 24 марта 2019

Имея информацию, полученную от всех 3 авторов, немного прочитав C и C # о переменных en datatypes, я скомпилировал следующее, что именно и делает то, что я хочу.

class Program
{
    public abstract class Koers
    {
        public string fonds { get; set; }
        public DateTime datum { get; set; }
        public Double koers { get; set; }
    }
    public class Historical : Koers
    {

    }

    private static void Display(List<Historical> cs)
    {
        Console.WriteLine();
        foreach (Historical item in cs)
        {
            Console.WriteLine("{0} {1} {2} ", item.fonds, item.datum.ToString(), item.koers);
        }
    }

    static void Main(string[] args)
    {
        Historical xkoers = new Historical();
        List<Historical> Historicals = new List<Historical>();

        Historicals.Add ( new Historical() { fonds = "EL1", datum = DateTime.Parse("2018-05-08"), koers = 310.1 } ) ;
        Historicals.Add ( new Historical() { fonds = "EL2", datum = DateTime.Parse("2018-06-08"), koers = 311.1 } ) ;
        xkoers.fonds = "AL3";
        xkoers.datum = DateTime.Parse("2018-05-08");
        xkoers.koers = 310.1;
        Historicals.Add(new Historical() { fonds=xkoers.fonds, datum=xkoers.datum, koers = xkoers.koers });
        xkoers.fonds = "AL4";
        xkoers.datum = DateTime.Parse("2018-06-08");
        xkoers.koers = 320.1;
        Historicals.Add(new Historical() { fonds = xkoers.fonds, datum = xkoers.datum, koers = xkoers.koers });
        xkoers.fonds = "Some other 5";
        xkoers.datum = DateTime.Parse("2019-06-08");
        xkoers.koers = 20.1;
        Historicals.Add(new Historical() { fonds = xkoers.fonds, datum = xkoers.datum, koers = xkoers.koers });

        Display(Historicals);
    }
}
0 голосов
/ 17 марта 2019

Причина, по которой он дублируется, заключается в том, что вы используете один и тот же экземпляр (ссылка на объект в памяти)

так что каждый раз, когда вы меняете xkoers, вы в конечном итоге меняете ссылку, на которую указывают все добавленные элементы в истории ...


Historical xkoers = new Historical() ;
Collection<Historical> Historicals = new Collection<Historical>();
xkoers.fonds = "AL1";
xkoers.datum = DateTime.Parse("2018-05-08");
xkoers.koers = 310.1;

можно сделать вот так

xkoers = new Historical() { fonds = "AL1", datum = DateTime.Parse("2018-05-08"), koers = 310.1)

, который изменит точку отсчета на новое место в памяти

затем добавьте это в свой список, и оно не должно повторяться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...