Interfejs ICloneable

0

Witam, mam dwa problemy, w jednym z przykładów, aby uniknąć późniejszego rzutowania zastosowano takie rozwiązanie

 
class myclass: ICloneable
    {
        public string imie;
        public string Imie
        {
            get
            {
                return imie;
            }
             set
            {
                imie = value;
            }
        }
     object ICloneable.Clone()
        {
            Console.WriteLine("z interfejsu");
            return this.Clone();
        }
        public myclass Clone()
        {
            Console.WriteLine("tu");
            return (myclass)this.MemberwiseClone();
        }
}

Czemu wyświetli się na konsoli tylko słowo "tu" bez "z interfejsu"? Jeśli się nie mylę to jest to jawna implementacja(ICloneable.Clone()) także jest prywatna i nie da się jej wywołać z zewnątrz także w którym momencie jest ona uruchamiana, bo musi się tak dziać skoro program działa?

Drugie pytanie to czemu mogę utworzyć obiekt interfejsu np.

ICloneable obiekt = new ICloneable();
 

lecz jeśli zadeklaruję własny interfejs to wówczas nie będę mógł utworzyć nowego a jedynie przypisać do obiektu, którego klasa dziedziczy po nim np.

interface my_interface
{
...
}

class myclass:my_interface
{
...
public static void Main()
{
myclass obiekt1 = new myclas();
my_interface my_inter = new my_interface(); // błąd
my_interface my_inter = obiekt1; //poprawnie
 
0
mariusz_wiersz napisał(a):

Czemu wyświetli się na konsoli tylko słowo "tu" bez "z interfejsu"? Jeśli się nie mylę to jest to jawna implementacja(ICloneable.Clone()) także jest prywatna i nie da się jej wywołać z zewnątrz także w którym momencie jest ona uruchamiana, bo musi się tak dziać skoro program działa?

Nie jest wywoływana.
Jak zrobisz coś takiego:

myclass obiekt1 = new myclass();
myclass o = obiekt1.Clone();

To wywołasz jedynie domyślną implementację metody Clone() czyli metodę public myclass Clone(). Jak chcesz wywołać jawną implementację, to musisz to jawnie zrobić czyli tak:

myclass my_object = (myclass)((ICloneable)obiekt1).Clone();

albo tak (chyba bardziej czytelnie?):

ICloneable my_inter = (ICloneable)obiekt1;
myclass my_object = (myclass)my_inter.Clone();

Standardowo stosuje się domyślną implementację. Jawna implementacja przydaje się wtedy gdy klasa implementuje kilka interfejsów, które mają jednakowe definicje metod. Wtedy, dzięki jawnej implementacji można odróżnić, która metoda jest z którego interfejsu.

Drugie pytanie to czemu mogę utworzyć obiekt interfejsu np.

ICloneable obiekt = new ICloneable();
 

To Ty wytłumacz nam jak to robisz bo ja jak coś takiego napiszę, to nie tylko program mi się nie kompiluje, ale Visual C# po zapisaniu pliku wyrzuca mi błąd:
"Cannot create an instance of the abstract class or interface 'System.ICloneable'"

0

Ale chciałem się dowiedzieć jak to się dzieje, że jednak jest wywoływana skoro poniższy kod działa:

  object ICloneable.Clone()
        {
            Console.WriteLine("z interfejsu");
            return this.Clone();
        }
        public myclass Clone()
        {
            Console.WriteLine("tutaj");
            return (myclass)this.MemberwiseClone();
        } 

dzięki temu nie muszę rzutować potem, gdyż od razu zwraca obiekt typu myclass. Nie rozumiem jak to się tam dostaje.

0

object ICloneable.Clone() nie jest wywoływana!
Sprawdź to sobie w debuggerze.
Możesz ją wywołać w taki sposób w jaki Ci to pokazałem.
Domyślnie ta metoda nie jest wywoływana.

0

To dzięki czemu zaprezentowany przykład działa? Usunięcie jawnej implementacji sprawi, że przestanie.

0

U mnie działa bez jawnej czyli bez tego:

object ICloneable.Clone()
{
    Console.WriteLine("z interfejsu");
    return this.Clone();
}

Natomiast bez domyślnej implementacji nie kompiluje się.

0

jak odpalić debuggera żeby przekonać się o tym? nie korzystałem jeszcze do tej pory. Dzięki za odpowiedź w temacie.

0

F5 - run debugger
F10 - step over
F11 - step into
Tu masz prezentację:
http://msdn.microsoft.com/en-US/vstudio/ee672313.aspx

0

To dzięki czemu zaprezentowany przykład działa?

Jeżeli bez żadnego interfejsu zdefiniujesz metodę o nazwie Clone, i ją odpalisz, to kod oczywiście zadziała, bo dlaczego by nie?

Usunięcie jawnej implementacji sprawi, że przestanie.

Wtedy masz dwie metody różniące się tylko zwracanym typem, co się nie skompiluje.

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