Rodrigo Kumpera Weblog

Meus achados sobre tecnologia

A beleza do sistema de tipos do C#

July 14th, 2011 · No Comments

Outro dia me apresentaram o código abaixo com um dúvida bem boba. Esse código em C# abusa um pouco de uma das novidades da última revisão da linguagem, tipos genéricos variantes. Vamos ao código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface A<in B> { }
 
interface B<in A> { }
 
class X : A<B<X>> { }
 
class Y : B<A<Y>> { }
 
class Test
{
	static void Main ()
	{
		A<Y> x = new X ();
	}
}

O código é um enrolado. A parte mais importante é entender interface A<in B> que é a declaração de A contravariante em B. Isso significa, a grosso modo, que A<object> instanceof A<string> == true.

A dúvida é se a atribuição A<Y> x = new X (); é válida. Vou usar <: como notação para
pode ser atribuido em, como em string <: object.

X <: A<Y> //X é uma classe e A uma interface, logo verificamos as interfaces de X
A<B<X>> <: A<Y> //Duas instâncias diferentes do mesmo tipo genérico. Por ser contravariante no primeiro parâmetro, verificamos ele
 
//Note que contravariância significa verificar na ordem inversa
Y <: B<X>  //Y é uma classe e B uma interface, logo verificamos as interfaces de Y
B<A<Y>> <: B<X> //Novamente duas instancias de um tipo contravariante, verificamos o primeiro parâmetro
 
X <: A<Y>

Calma la, voltamos a definição original! Sim, voltamos, existe um ciclo nessa verificação e ela não pode ser decidida. Tanto o compilador como o sistema de tipos são não capazes de decidir. A solução pragmática é simplesmente recusar essa atribuição.

Quem imaginaria que o novo sistema de tipos do C# possui casos que não decidíveis. Pois é, e não fica só nisso, existem outros problemas envolvendo variância como ambiguidade no caso de últimas interfaces que merecem outro artigo.

Tags: Programming · Programming language Theory · language design

0 responses so far ↓

  • There are no comments yet...Kick things off by filling out the form below.

Leave a Comment