Generische Klasse und where Problem

07/27/2017 13:43 xShizoidx#1
Hallo,

ich habe gerade einen kleinen Test mit Generics gemacht, jedoch bekomme ich nur einen Fehler, wenn ich die Liste übergeben will bzw. genau bei
List<string> myStringList = ToStringListConverter<List<int>>.ToYourList(numbers);

Woran liegt das ? List implementiert ja IEnumerable.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> numbers = new List<int>
            {
                3,
                6,
                8
            };
            List<string> myStringList = ToStringListConverter<List<int>>.ToYourList(numbers);
        }

        static class ToStringListConverter<T> where T : IEnumerable<T>
        {

            public static List<string> ToStringList(T yourList)
            {
                List<string> result = new List<string>();
                foreach (T item in yourList)
                {
                    result.Add(item.ToString());
                }
                return result;
            }
        }
    }
}
07/27/2017 14:43 IceTrailer#2
Also zunächst würde ich dir empfehlen, um Fehler zu vermeiden var zu verwenden.
heißt konkret statt

Code:
List<string> result = new List<string>();
solltest du

Code:
var result = new List<string>();
verwenden.

Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new List<int>
            {
                3,
                6,
                8
            };
            var myStringList = ToStringListConverter.ToStringList(numbers);
        }
    }
    // Lösch den Quatsch mit T .. und IEnumerable brauchst du auch nicht
    static class ToStringListConverter
    {
        public static List<string> ToStringList(IList yourlist)
        {
            var result = new List<string>();

            foreach (var item in yourlist)
            {
                result.Add(item.ToString());
            }
            return result;
        }
    }

}
Edit:

Mir ist aufgefallen, dass du IEnumerable ja gar nicht vererben musst
07/27/2017 15:17 xShizoidx#3
Quote:
Originally Posted by IceTrailer View Post
Also zunächst würde ich dir empfehlen, um Fehler zu vermeiden var zu verwenden.
heißt konkret statt

Code:
List<string> result = new List<string>();
solltest du

Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new List<int>
            {
                3,
                6,
                8
            };
            var myStringList = ToStringListConverter.ToStringList(numbers);
        }
    }
    // Lösch den Quatsch mit T .. und IEnumerable brauchst du auch nicht
    static class ToStringListConverter
    {
        public static List<string> ToStringList(IList yourlist)
        {
            var result = new List<string>();

            foreach (var item in yourlist)
            {
                result.Add(item.ToString());
            }
            return result;
        }
    }

}
Edit:

Mir ist aufgefallen, dass du IEnumerable ja gar nicht vererben musst
Moin,

warum sollte ich var verwenden in diesem Fall ? Wenn ich List<string> direkt ausschreibe, dann sehe ich ja , falls ein Fehler auftritt , weil mir das VS anzeigt. Bei var treten meiner Meinung nach in diesem Fall ja eher Fehler auf, wenn ich mich z.B. auf der rechten Seite, wo List<string> steht, verschreibe.

Ich möchte nicht überprüfen, ob es von einem Interface ableitet, ich möchte es generisch haben, das war nur ein Test von mir und die Funktion wird in der Praxis sowieso nicht verwendet, ich will nur wissen, wo der Fehler lag
07/27/2017 15:34 IceTrailer#4
Quote:
Originally Posted by xShizoidx View Post
Moin,

warum sollte ich var verwenden in diesem Fall ? Wenn ich List<string> direkt ausschreibe, dann sehe ich ja , falls ein Fehler auftritt , weil mir das VS anzeigt. Bei var treten meiner Meinung nach in diesem Fall ja eher Fehler auf, wenn ich mich z.B. auf der rechten Seite, wo List<string> steht, verschreibe.

Ich möchte nicht überprüfen, ob es von einem Interface ableitet, ich möchte es generisch haben, das war nur ein Test von mir und die Funktion wird in der Praxis sowieso nicht verwendet, ich will nur wissen, wo der Fehler lag
Naja erfahrungsgemäß kann ich sagen, dass ich mehr Fehler mach, wenn ich es ausschreib (mehr zu schreiben, vor allem mit den spitzen "ungewöhnlichen" Klammern, die man ja selten eingibt)

Wenn du es generisch haben willst, würde ich dir empfehlen mal weiter im Internet zu suchen, wie du das mit List<T> machst..
07/27/2017 18:28 Mikesch01#5
Tag. Hier liegt wahrscheinlich der Fehler:
Code:
static class ToStringListConverter<T> where T : IEnumerable<T>
Einfach zu
Code:
public static class ToStringListConverter<T> where T : IEnumerable<T>
machen.

p.s. wenn ein Fehler vorhanden ist, dann bitte immer die Fehlermeldung mitschicken. Sonst kann man raten was der Fehler sein könnte.
07/27/2017 20:50 xShizoidx#6
Quote:
Originally Posted by Mikesch01 View Post
Tag. Hier liegt wahrscheinlich der Fehler:
Code:
static class ToStringListConverter<T> where T : IEnumerable<T>
Einfach zu
Code:
public static class ToStringListConverter<T> where T : IEnumerable<T>
machen.

p.s. wenn ein Fehler vorhanden ist, dann bitte immer die Fehlermeldung mitschicken. Sonst kann man raten was der Fehler sein könnte.
Vielen Dank für die schnelle Antwort.
Das ist leider nicht der Fehler :
Code:
Schweregrad	Code	Beschreibung	Projekt	Datei	Zeile	Unterdrückungszustand
Fehler	CS0311	Der Typ "System.Collections.Generic.List<int>" kann nicht als Typparameter "T" im generischen Typ oder in der generischen Methode "Program.ToStringListConverter<T>" verwendet werden. Es ist keine implizite Verweiskonvertierung von "System.Collections.Generic.List<int>" in "System.Collections.Generic.IEnumerable<System.Collections.Generic.List<int>>" vorhanden.	ConsoleApp33	c:\users\torge\documents\visual studio 2017\Projects\ConsoleApp33\ConsoleApp33\Program.cs	19	Aktiv
07/27/2017 21:06 Mikesch01#7
Das müsste hier dran liegen:
Code:
static class ToStringListConverter<T> where T : IEnumerable<T>
Stell dir vor, wir benutzen für T nun List<int>. Hier ist nun die Ersetzung im Programm wiefolgt:
Code:
static class ToStringListConverter<List<int>> where List<int> : IEnumerable<List<int>>
Das macht natürlich wenig Sinn, wenn IEnumerable nun als Typen die List selbst hat.

Deshalb reicht es vollkommen aus, wenn T nicht von einem generischen IEnumerable ableitet:
Ein gesetztes Beispiel:
Code:
static class ToStringListConverter<List<int>> where List<int> : IEnumerable
Hier ist nun T generisch und kann beliebig angegeben werden. Hauptsache T ist nun abgeleitet von IEnumerable, was ja List ist.

Allgemeiner, richtiger Code:
Code:
static class ToStringListConverter<T> where T : IEnumerable
07/28/2017 20:08 xShizoidx#8
Quote:
Originally Posted by Mikesch01 View Post
Das müsste hier dran liegen:
Code:
static class ToStringListConverter<T> where T : IEnumerable<T>
Stell dir vor, wir benutzen für T nun List<int>. Hier ist nun die Ersetzung im Programm wiefolgt:
Code:
static class ToStringListConverter<List<int>> where List<int> : IEnumerable<List<int>>
Das macht natürlich wenig Sinn, wenn IEnumerable nun als Typen die List selbst hat.

Deshalb reicht es vollkommen aus, wenn T nicht von einem generischen IEnumerable ableitet:
Ein gesetztes Beispiel:
Code:
static class ToStringListConverter<List<int>> where List<int> : IEnumerable
Hier ist nun T generisch und kann beliebig angegeben werden. Hauptsache T ist nun abgeleitet von IEnumerable, was ja List ist.

Allgemeiner, richtiger Code:
Code:
static class ToStringListConverter<T> where T : IEnumerable
Daran liegt es leider auch nicht
08/01/2017 01:11 Shawak#9
so klappts

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class Program
    {
        public static void Main(string[] args)
        {
            List<int> numbers = new List<int>
            {
                3,
                6,
                8
            };
            List<string> myStringList = ToStringListConverter<List<int>>.ToStringList(numbers);
            foreach(var item in myStringList)
                Console.WriteLine(item);
        }

        static class ToStringListConverter<T> where T : IEnumerable<int>
        {

            public static List<string> ToStringList(T yourList)
            {
                List<string> result = new List<string>();
                foreach (var item in yourList)
                {
                    result.Add(item.ToString());
                }
                return result;
            }
        }
    }
}
Wobei das halt grundsätzlich Schwachsinn ist und du die Funktionen überladen solltest.