Wątek przeniesiony 2015-04-08 16:39 z C# i .NET przez somekind.

GetEnumerator() coś nie tak z inicjalizacją obiektu

1

Hej
mam taki mały problemik :)

public IEnumerator<string> GetEnumerator()
        {
            return new Model { FilesList = FilesList };
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return new Model { FilesList = FilesList };
        }

Widać co się dzieje... mam obiekt Model i inicjalizuję mu propercję FilesList = FilesList... działa ale coś Mi tu śmierdzi... ta sama propercja dostaje samą siebie? mógłby ktoś zerknąć i mnie porządnie opier... bo chcę go poprawić żeby było po bożemu :)

Pzdr
Łukasz

0

daje + za 'propercje' :) ale moze najpierw sproboj skompilowac swoj kod przed zadawaniem podchwytliwych pytan
(jesli jestem w bledzie i to cos sie kompiluje to stawiam ze masz gdzies w klasie skladowa o tej samej nazwie?)

0

Może powiedz najpierw o tym co w ogóle próbujesz osiągnąć.

0

Tak mam w klasie składową

public List<string> FilesList { get; set; }
        
1

Ale przecież typ Model to nie typ IEnumerator, to przecież nie ma prawa się skompilować oO A przecież kompilator podaje komunikat, jest w nim - oprócz samego faktu, że to błąd - pewna treść. Zwykle wystarczy ją przeczytać ze zrozumieniem albo chociaż wrzucić na google.
Zgaduję. że powinieneś zwrócić FilesList.GetEnumerator().

BTW - WTF z inicjalizacją inline w GetEnumerator? To tak jakbyś poszedł do mięsnego wypożyczyć listę książek w momencie kiedy to czego potrzebujesz to bułki. Po bułki to do piekarni, chopie.

0

Klasa wygląda mniej więcej tak :

 public class Model : IModel, IEnumerator<string>
    {
       
       
        private int position = -1;
        public List<string> FilesList { get; set; }
       



        

        public IEnumerator<string> GetEnumerator()
        {
            return new GeneratorModel { FilesList = FilesList };
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return new GeneratorModel { FilesList = FilesList };
        }

        public bool MoveNext()
        {
            ++position;
              if (position < FilesList.Count)
              {
                  
                 /// operation
              }
            return (position < FilesList.Count);
        }


        public void Reset()
        {
            position = -1;
        }

        public string Current
        {
            get
            {
                try
                {
                    return FilesList[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }

        object IEnumerator.Current
        {
            get { return Current; }
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

OK. Mi się to kompiluję więc nie wiem gdzie widzicie problem :(? Jeśli widzicie rażące błędy to zapraszam :)

0

A tak konkretniej :) ?

0

wyglada na to ze napisales sporo bezuzytecznego kodu, jak dla mnie wszystkie metody sa do wywalenia (jak i rowniez pole position).
jesli juz koniecznie chcesz zrobic 'enumerowalny' wrapper na ta liste to zaimplementuj IEnumerable<string> zamiast IEnumerator<string>

1

GC.SuppressFinalize() w Dispose - po co Ci sztuczne wydłużanie czasu życia obiektu, który już został "zniszczony"?

Obie wersje GetEnumerator() - po co tworzenie nowego obiektu, żeby iterować po FilesList? Tak jak już pisałem, w obu przypadkach wystarczy return FilesList.GetEnumerator().

Tu zaś ciekawa konstrukcja - łapanie wyjątku tylko po to, żeby rzucić inny wyjątek. Nawet nie przekazujesz faktycznie łapanego wyjątku do InnerException wyjątku rzucanego. Tak się nie robi. Modyfikujesz domyślne zachowanie listy, piszesz dodatkowe linijki kodu które trzeba przykryć testem, a wszystko tylko po to, żeby dla tego jednego przypadku mieć inny wyjątek. Moim zdaniem to zła praktyka programistyczna.

                try
                {
                    return FilesList[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }

Generalnie robisz enkapsulację, kiedy odpowiedniejsze wydaje się dziedziczenie (po List<T> albo po ReadOnlyCollection<T>).

0

Dzięki za odpowiedź. Zrozumiałem, że <ort>nie potrzebnie</ort> pisałem ten kod. :) ale trochę ćwiczeń nie zabrakło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1