Jawna implementacja metod interfejsu

0

Cześć

Zastanawiam się czemu przy jawnej implementacji metody z interfejsu nie mogę zrobić takiej metody publicznej:

        public void ITransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3: {0}", z1);
        }

Dostaję komunikat:

The modifier 'public' is not valid for this item
W pisaniu kodu mi to nie przszkadza jakoś specjalnie, bo wystarczy się dostosować ale spać przez to nie mogę.

4

Ponieważ możesz zaimplementować dzięki temu kilka metod o takiej samej sygnaturze, ale z innych interfejsów:

class MojaKlasa : ITransakcje, IInneTransakcje
{
        public void ITransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z ITransakcje: {0}", z1);
        }

        public void IInneTransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z IInneTransakcje: {0}", z1);
        }
}

Gdyby te metody miały być publicznie widoczne w klasie to przy wywołaniu bezpośrednio na obiekcieobiekt.Metoda3(42) nie wiadomo by było, która z nich ma zostać wywołana.

var obiekt = new MojaKlasa();
(obiekt as ITransakcje).Metoda3(42); // odpala się pierwsza metoda
(obiekt as IInneTransakcje).Metoda3(42); // odpala się druga metoda
obiekt.Metoda(42); // która ma się odpalić?
1

Metody z interfejsu sa zawsze publiczne, wiec nie ma sensu I jest bledem umieszczanie modyfikatorow dostepu.

0
mad_penguin napisał(a):

Ponieważ możesz zaimplementować dzięki temu kilka metod o takiej samej sygnaturze, ale z innych interfejsów:

class MojaKlasa : ITransakcje, IInneTransakcje
{
        public void ITransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z ITransakcje: {0}", z1);
        }

        public void IInneTransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z IInneTransakcje: {0}", z1);
        }
}

Gdyby te metody miały być publicznie widoczne w klasie to przy wywołaniu bezpośrednio na obiekcieobiekt.Metoda3(42) nie wiadomo by było, która z nich ma zostać wywołana.

var obiekt = new MojaKlasa();
(obiekt as ITransakcje).Metoda3(42); // odpala się pierwsza metoda
(obiekt as IInneTransakcje).Metoda3(42); // odpala się druga metoda
obiekt.Metoda(42); // która ma się odpalić?

Ale to nie po to używa sę np. takiej składni?:

            Program p1 = new Program();
            ITransakcje transakcje = (ITransakcje)p1;
            transakcje.Metoda3(1);

            Program p2 = new Program();
            ITransakcje2 transakcje2 = (ITransakcje2)p2;
            transakcje2.Metoda3(1);

Lub podany przez Ciebie przypadek.
Samo rzutowanie określa mi jaką metode chcę użyć. Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

0
lion137 napisał(a):

Metody z interfejsu sa zawsze publiczne, wiec nie ma sensu I jest bledem umieszczanie modyfikatorow dostepu.

Przy implementowaniu kompilator wymusza na mnie podanie modyfikatora dostępu, przy niejawnej implementacji.

1
rubesom napisał(a):

Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Jawnie implementowane metody interfejsu nie mogą być publiczne, bo jak wcześniej ustaliliśmy prowadziłoby to do paradoksu, stąd umieszczanie przy nich modyfikatora public jest bez sensu, stąd kompilator nie zezwala na to :)

1
mad_penguin napisał(a):
rubesom napisał(a):

Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Jawnie implementowane metody interfejsu nie mogą być publiczne, bo jak wcześniej ustaliliśmy prowadziłoby to do paradoksu, stąd umieszczanie przy nich modyfikatora public jest bez sensu, stąd kompilator nie zezwala na to :)

Oczywiście to jest prawda jeśli w klasie są dwie takie metody. Jeśli miałaby być jedna, to w sumie czemu nie?

0
rubesom napisał(a):

Samo rzutowanie określa mi jaką metode chcę użyć. Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Zabezpieczenie? Chyba tylko przed brakiem logicznego kodu. Gdybyś mógł nadać public, to nie musiałbyś rzutować na interfejs, bo metoda byłaby dostępna na poziomie zmiennej typu klasy. I skąd wiadomo by było, którą wtedy metodę wywołać?

TomRiddle napisał(a):

Oczywiście to jest prawda jeśli w klasie są dwie takie metody. Jeśli miałaby być jedna, to w sumie czemu nie?

A po co komplikować kompilator dla jakiegoś przypadku brzegowego, który nie miałby sensu praktycznego?

0
somekind napisał(a):
rubesom napisał(a):

Samo rzutowanie określa mi jaką metode chcę użyć. Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Zabezpieczenie? Chyba tylko przed brakiem logicznego kodu. Gdybyś mógł nadać public, to nie musiałbyś rzutować na interfejs, bo metoda byłaby dostępna na poziomie zmiennej typu klasy. I skąd wiadomo by było, którą wtedy metodę wywołać?

TomRiddle napisał(a):

Oczywiście to jest prawda jeśli w klasie są dwie takie metody. Jeśli miałaby być jedna, to w sumie czemu nie?

A po co komplikować kompilator dla jakiegoś przypadku brzegowego, który nie miałby sensu praktycznego?

Implementacja jednego interfejsu to przypadek brzegowy? ;|

0

Część metod z interfejsu może mieć explicit a część implicit implementation. Możesz po prosty wybrać implicit dla tych metod które mają być publiczne i gotowe.

0
TomRiddle napisał(a):

Implementacja jednego interfejsu to przypadek brzegowy? ;|

Co najmniej brzegowy, a może nawet i szalony. W jakim celu implementować explicite jeden interfejs?

0
somekind napisał(a):
TomRiddle napisał(a):

Implementacja jednego interfejsu to przypadek brzegowy? ;|

Co najmniej brzegowy, a może nawet i szalony. W jakim celu implementować explicite jeden interfejs?

Skoro tak, to ktoś by powiedział że pisanie this.field (zamiast field, gdy nie ma zmiennej lokalnej field.) to jest brzegowy/szalony pomysł, i powinno się tego zakazać. Po co pisać this explicite, skoro jest tylko jedno pole field?

0

Używanie this jest kwestią konwencji. Zaimplementowanie interfejsu explicite jest kwestią potrzeby, która występuje w konkretnych sytuacjach. W jakiej sytuacji występuje potrzeba zaimplementowania jednego interfejsu explicite? To generalnie byłoby wyłącznie utrudnieniem, więc po co to robić?
Chciałbym zobaczyć konkretny przykład z życia.

1

Prosz - dwie klasy, które implementują jeden interfejs, całkowicie bez konieczności implementacji dodatkowych:

interface SomeStrategy {
  void doSomething();
}

class StrategyA: SomeStrategy {
  /* ... */
}

class StrategyB: SomeStrategy {
  /* ... */
}
0

@Patryk27: nie podałeś ciała klas, więc nie wiadomo, czy interfejsy zostały zaimplementowane explicite, czy nie.
A jeśli explicite, to ponawiam pytanie - w jakim celu?

0
somekind napisał(a):

Używanie this jest kwestią konwencji. Zaimplementowanie interfejsu explicite jest kwestią potrzeby, która występuje w konkretnych sytuacjach. W jakiej sytuacji występuje potrzeba zaimplementowania jednego interfejsu explicite? To generalnie byłoby wyłącznie utrudnieniem, więc po co to robić?
Chciałbym zobaczyć konkretny przykład z życia.

Z jednej strony rozumiem czemu możesz uważać że to jest redundant. Z drugiej nie rozumiem, czemu miałoby to komuś przeszkadzać. Można by też powiedzieć że !! w silnie typowanych językach jest redundant, ale nikt nie wyobraża sobie uważana więcej niż jednego wykrzyknika jako błąd.

0

@TomRiddle: nie uważam tego za redundantne tylko za bezsensowne, bo jedynie utrudnia. A nawet jeśli to ma sens w jakimś przypadku, to jest tak rzadki, że nie warto w tym celu komplikować kompilatora.

I serio pytam - możesz podać jakiś konkretny sensowny przykład użycia?

0
somekind napisał(a):

@TomRiddle: nie uważam tego za redundantne tylko za bezsensowne, bo jedynie utrudnia. A nawet jeśli to ma sens w jakimś przypadku, to jest tak rzadki, że nie warto w tym celu komplikować kompilatora.

I serio pytam - możesz podać jakiś konkretny sensowny przykład użycia?

No z definicji coś redundantego nie ma przypadku użycia, podobnie jak == true. Modyfikatory public są redundant w interfejsach (w Javie) ale nikt się nie czepia żeby ich zakazać. Albo return w metodach void, Skoro w innych przypadkach się da, to po co robić z tego przypadek szczególny?

0
TomRiddle napisał(a):

No z definicji coś redundantego nie ma przypadku użycia

Ale nie tylko redundantne rzeczy mogą nie mieć przypadku użycia.

Modyfikatory public są redundant w interfejsach (w Javie) ale nikt się nie czepia żeby ich zakazać.

Ale to już problem Javy.

Albo return w metodach void,

Ależ wcale nie jest redundantny, jest przydatny i całkiem często stosowany.

Skoro w innych przypadkach się da, to po co robić z tego przypadek szczególny?

Przypadek ogólny jest taki, że w przypadku implementacji metody interfejsu explicite nie można jej nadać modyfikatora dostępu public. Ty chcesz zrobić przypadek szczególny, że jeśli klasa implementuje tylko jeden taki interfejs (więc nie ma kolizji nazw metod), to żeby się dało nadać modyfikator dostępu.
No więc pytanie do Ciebie - po co robić przypadek szczególny?

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