Sprawdzanie typu

0

Cześć, mam pytanie odnoście sprawdzania typu. Chciałbym aby w sekcji if instrukcje się wykonały gdy mamy kolekcję implementującą interfejs IEnumerable której elementami są obiekty/struktury implementujące IComparable. Mam niestety z tym kłopot.

Spójrzmy na ten kod:

static void Main(string[] args)
        {
           
            object stringList = new List<string> { "Text1", "Text2" };
            object intList = new List<int> { 1, 2, 3 };

            if (stringList is IEnumerable<IComparable>)
                Console.WriteLine("Test1");

            if (intList is IEnumerable<IComparable>)
                Console.WriteLine("Test2");
        }
  1. Dlaczego wykonanie wchodzi do pierwszego ifa, a do drugiego już nie? Strzelam że to może być związane z tym iż int jest strukturą, a one nie mogą dziedziczyć.
  2. Jest jakiś sensowny sposób osiągnięcia rezultatu opisanego na początku postu?
2

Tu nie ma żadnego dziedziczenia. Generalnie wszystko jest tutaj https://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type

Możesz to sprawdzać refleksją - GetType, GetInterfaces i lecisz.

0

Nie wiem czy w tym zastosowaniu refleksja to dobry wybór. Napiszę może dokładnie z jakim problemem się mierzę, może za bardzo kombinuję a rozwiązanie jest proste.

Mam metodę generyczną o poniższej sygnaturze:

GenericMethod<T>(IEnumerable<T> prop1, IEnumerable<T> prop2) where T: IComparable<T>

Wykorzystywana jest ona w innej metodzie która przyjmuje parametry typu object:

private bool SampleMethod(object field1, object field2)
        {
            if (field1 is IEnumerable<string> listStringA && field2 is IEnumerable<string> listStringB)
                return GeneticMethod(listStringA, listStringB);
            else if (field1 is IEnumerable<int> listIntA && field2 is IEnumerable<int> listIntB)
                return GeneticMethod(listIntA, listIntB);
            else if(field1 is IEnumerable<double> listDoubleA && field2 is IEnumerable<double> listDoubleB)
                return GeneticMethod(listDoubleA, listDoubleB);
            //some lines not shown

            return false;
        }

Jak widać nie za fajnie to wygląda. Tych ifów jest jeszcze kilka. Co w takiej sytuacji byście poradzili, aby ten kod lepiej wyglądał?

0

Nie przyjmować object albo nie używać metody generycznej.

0

a czemu do SampleMethod przychodzą tak nieustandaryzowane dane? Czemu nie może to być metoda generyczna?
Co prawda lista nie spełnia warunku is IEnumerable<IComparable> ale poszczególne inty już spełniają warunek is IComparable więc możesz po prostu próbować rzutować

((IEnumerable)prop1).Cast<IComparable>()

to poprawnie zrzutuje całą listę w przypadku dowolnego enumerable int lub string - niestety wyjątek może polecieć w momencie iterowania wewnątrz "GenericMethod" jeśli któryś element nie będzie go implementował. Jedyne podejście żeby się upewnić to albo użyć refleksji, albo zmaterializować na tym etapie listę jakimś .ToList()

możesz użyć też łagodniejszego podejścia:

(prop1 as IEnumerable)?.OfType<IComparable>()

to da null jeśli obiekt nie jest IEnumerable, a jeśli jest to zwróci tylko te elementy które są IComparable (pomijając po cichu te które się nie kwalifikują)

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