operator implicit care utilizează interfețe (Programare, C#, Generice, Compilator De Construcție, Turnare, Conversie Implicită)

Michael Meadows a intrebat.

Am o clasă generică pentru care încerc să implementez turnarea implicită a tipurilor. Deși în mare parte funcționează, nu va funcționa pentru turnarea interfețelor. La o investigație suplimentară, am descoperit că există o eroare de compilare: „User-defined conversion from interface” care se aplică. Deși înțeleg că acest lucru ar trebui să fie aplicat în unele cazuri, ceea ce încerc să fac pare a fi un caz legitim.

Iată un exemplu:

public class Foo<T> where T : IBar
{
    private readonly T instance;

    public Foo(T instance)
    {
        this.instance = instance;
    }
    public T Instance
    {
        get { return instance; }
    }
    public static implicit operator Foo<T>(T instance)
    {
        return new Foo<T>(instance);
    }
}

Cod pentru a-l utiliza:

var concreteReferenceToBar = new ConcreteBar();
IBar intefaceReferenceToBar = concreteReferenceToBar;
Foo<ConcreteBar> concreteFooFromConcreteBar = concreteReferenceToBar;
Foo<IBar> fooFromConcreteBar = concreteReferenceToBar;
Foo<IBar> fooFromInterfaceBar = intefaceReferenceToBar; // doesn't work

Știe cineva o soluție de rezolvare, sau poate cineva să explice într-un mod satisfăcător de ce nu ar trebui să fiu capabil să fac cast interfaceReferenceToBar implicit în Foo<IBar>, , din moment ce în cazul meu nu este convertit, ci doar conținut în Foo?

EDIT:Se pare că covarianța ar putea oferi salvarea. Să sperăm că specificația C# 4.0 permite turnarea implicită a tipurilor de interfață folosind covarianța.

1 răspunsuri
Adam Hughes

Motivul pentru care nu puteți face acest lucru este că este interzis în mod specific în specificația limbajului C#:

Sursa: ECMA-334 secțiunea 15.10.4.

O clasă sau o structură poate declara o conversie de la un tip de sursă S la un tip țintă T, cu condiția ca toate cele de mai jos să fie adevărate:

  • Nici S, nici T nu este object sau un tip de interfață.

și

Conversiile definite de utilizator nu sunt permise pentru a converti de la sau cătretipuri de interfață. În special, această restricție garantează că transformările definite de utilizator au loc atunci când se face conversia către un tip de tip tip de interfață, și că o conversie către un tip de interfațătip de interfață reușește numai dacă obiectul care se convertește implementează efectiv tipul de interfață specificat.tipul de interfață specificat.

Comentarii

  • Înțeleg că face parte din specificație, turnarea implicită a unei interfețe ar trebui să fie invalidă în anumite cazuri, dar în toate? –  > Por Michael Meadows.
  • Sunt de acord cu tine, nu știu de ce au făcut-o invalidă pentru toate cazurile. În acest caz, puteți stabili la compilare că castul este (ar trebui să fie) valid. –  > Por Adam Hughes.
  • I cred că că restricția privind distribuția implicită a interfețelor are legătură cu modul în care este implementată interoperabilitatea COM. COM utilizează QueryInterface, pe care .NET o gestionează automat. Permițând conversia implicită a interferează. –  > Por Mark.
  • @MichaelMeadows, ar fi bine să citiți răspunsurile lui Adam Houldsworth și Eric Lippert la întrebarea mea similară în contextul C# 4.0. –  > Por gregsdennis.
  • Se explică undeva de ce au luat această decizie? –  > Por Hatchling.