ďťż

Ładny brzuch

Mam interfejs:

interface ITestInterface { int Value { get; set; } }

i klasy go implementujące:

class TestClassA : ITestInterface { public in Value { get; set; } } class TestClassB : ITestInterface { public in Value { get; set; } }

Klasy te dostarcza użytkownik (deweloper), może więc utworzyć kolejne klasy implementujące ITestInterface. W programie w jednym miejscu porównuję 2 klasy implementujace ITestInterface, o ile jest to możliwe.

Moje pytanie brzmi - w jaki sposób napisać porównywanie klas implementujacych interfejs tak, abym mógł sprawdzić, czy można je porównać?

Powinno to być coś w rodzaju:

if (mozna_porownac(A, B)) porownaj(A, B); else if (mozna_porownac(B, A)) porownaj(B, A); else throw new Exception();

Myślałem, żeby wykorzystać przeciążanie operatorów, ale to niemożliwe w interfejsie ani klasie abstrakcyjnej. Próbowałem wykorzystać interfejs IComparable<typ>, jednak nie wiem jak pomiędzy "<" i ">" wstawić "zmienną" określającą typ innej klasy.
Użytkownik ROB4L edytował ten post 18 październik 2009, 20:25


Porównanie po typach:
public interface IInterface { Type MyType { get; } } public class Class1 : IInterface, IComparable<IInterface> { public Type MyType { get { return this.GetType(); } } public int CompareTo(IInterface other) { return Convert.ToInt32(MyType == other.MyType); } } public class Class2 : IInterface, IComparable<IInterface> { public Type MyType { get { return this.GetType(); } } public int CompareTo(IInterface other) { return Convert.ToInt32(MyType == other.MyType); } }
Po wartości
public interface IInterface //: IComparable<IInterface> { int Value { set; get; } } public class Class1 : IInterface, IComparable<IInterface> { private int x; public int Value { get { return x; } set { x = value; } } public int CompareTo(IInterface other) { return Value.CompareTo(other.Value); } } public class Class2 : IInterface, IComparable<IInterface> { private int x; public int Value { get { return x; } set { x = value; } } public int CompareTo(IInterface other) { return Value.CompareTo(other.Value); } }
Mam nadzieję, że coś Ci to podpowie.

[edit]
Zobacz jeszcze http://stackoverflow...type-comparison
Użytkownik lszk edytował ten post 18 październik 2009, 21:23
Problem polega na tym, że porównywane pola nie muszą się nazywać tak samo. Nie muszą nawet być tego samego typu. Wszystko zależy od inwencji twórczej osoby piszącej nową klasę.

Oczywiście mogę zrobić tak, że w CompareTo będzie za pomocą if-ów sprawdzany każdy typ.
if (other is ClassA) ... else if (other is ClassB) ...

itp., ale to kiepskie rozwiązanie. Nawet nie ze względu na niefajną postać - chodzi o to, że nie mogę "z zewnątrz" sprawdzić, czy klasa pozwala na porównanie z inną klasą. Jest mi to potrzebne, bo wiadomo, że z reguły tylko jedna z porównywanych klas będzie posiadała metodę do porównywania z drugą - nie mogę przecież wymagać aby klasy już istniejące "radziły sobie" z klasami nowymi.

//EDIT:
Potrzebowałbym coś w rodzaju:
Typ zmienna = pobierz_typ(klasa_implementująca_interfejs); if (klasa is IComparable<zmienna>) ...
lub:
((zmienna)klasa_impl_interfejs).metoda_klasy_typu_zmienna_nie_bedaca_w_interfejsie( ); //rzutowanie na typ pobrany ze zmiennej przechowującej tpy
Użytkownik ROB4L edytował ten post 19 październik 2009, 20:18

Potrzebowałbym coś w rodzaju:
Typ zmienna = pobierz_typ(klasa_implementująca_interfejs); if (klasa is IComparable<zmienna>) ...

To zobacz z tym IsAssignableFrom z linka powyżej.
Class1 c = new Class1(); Type t = typeof(IInterface); Type class1Type = c.GetType(); if (t.IsAssignableFrom(class1Type)) { Console.Write("Class1 dziedziczy po IInterface"); }

Może zainteresuj się też MEF-em. Ma to służyć do łatwego rozszerzania aplikacji o dodatkowe możliwości.
http://www.codeplex.com/MEF
Użytkownik lszk edytował ten post 19 październik 2009, 21:02


To że ona implementuje IInterface to wiem, bo ten interfejs jest łącznikiem pomiędzy logiką aplikacji a klasami użytkownika ;) Potrzebuję zmiennej, przechowującej typ, której będę mógł użyć do rzutowania lub sprawdzenia czy klasa implementuje interfejs oparty na tym typie - IComparable<typ>. Tak, abym mógł wywoływać metody znajdujące się w klasie implementującej IInterface, a nie będące częścią tego interfejsu. IsAssignableFrom wymaga podania konkretnej nazwy typu, a u mnie jakby sama nazwa typu musiałaby być zmienną.
Użytkownik ROB4L edytował ten post 19 październik 2009, 21:43
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • zsf.htw.pl
  •