Pergunta

Fundo:

Vamos supor que eu tenha a seguinte aula:

class Wrapped<T> : IDisposable
{
    public Wrapped(T obj)  { /* ... */ }

    public static implicit operator Wrapped<T>(T obj)
    {
        return new Wrapped<T>(obj);
    }

    public void Dispose()  { /* ... */ }
}

Como você pode ver, ele fornece um operador de conversão de tipo implícito para TWrapped<T>. Por fim, gostaria de poder usar esta classe da seguinte maneira:

interface IX  { /* ... */ }

class X : IX  { /* ... */ }

...

IX plainIX = new X();

using (Wrapped<IX> wrappedIX = plainIX)
{
    /* ... */
} 

Problema:

No entanto, o tipo de conversão no acima using A cláusula falha. Enquanto eu posso atribuir um new X() Diretamente a wrappedIX, Não tenho permissão para atribuir nada do tipo IX para isso. O compilador reclamará com o seguinte erro:

Erro do compilador CS0266: Não é possível converter implicitamente tipo 'IX' em 'embrulhadou003CIX> '. Existe uma onversão explícita (você está perdendo um elenco?)

Eu não entendo isso. Qual é o problema aqui?

Foi útil?

Solução

Eu acredito que é porque IX é uma interface. O compilador pensa que talvez um valor do tipo IX já poderia ser derivado de Wrapped<IX> (ainda que Wrapped<T> está selado) para que não use a conversão.

Os detalhes são bastante complicados, nas seções 6.4.3 e 6.4.4 da especificação C# 3.0. Basicamente porque IX é uma interface, não é "abrangida por" quaisquer tipos, o que significa uma etapa posterior em 6.4.4 falha.

Eu sugiro que você crie um tipo não genérico Wrapped Com este método:

public static Wrapped<T> Of<T>(T item)
{
    return new Wrapped<T>(item);
}

Então você pode apenas escrever:

using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))

Basicamente, as conversões podem ser um pouco complicadas por várias razões - os métodos simples geralmente são mais fáceis de entender, IMO.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top