2010-04-07 13 views
7

Tengamos una siguiente ejemplo:Espacio de nombres con ámbito alias para tipos genéricos en C#

public class X { } 
public class Y { } 
public class Z { } 

public delegate IDictionary<Y, IList<Z>> Bar(IList<X> x, int i); 

public interface IFoo 
{ 
    // ... 
    Bar Bar { get; } 
} 

public class Foo : IFoo 
{ 
    // ... 
    public Bar Bar 
    { 
     get 
     { 
      return null; //... 
     } 
    } 
} 

void Main() 
{ 
    IFoo foo; //= ... 
    IEnumerable<IList<X>> source; //= ... 
    var results = source.Select(foo.Bar); // <- compile error here 
} 

El compilador dice:

Los argumentos de tipo de método 'System.Linq.Enumerable.Select (Sistema .Collections.Generic.IEnumerable, System.Func) 'no se puede deducir del uso. Pruebe especificando los argumentos de tipo explícitamente.

Es porque, no puede convertir Bar en Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

Sería grandioso si pudiera crear tipos alias de tipo de espacio de espacios de tipo genérico en C#. Entonces definiría Bar no como un delegado, sino que lo definiría como un alias de ámbito de espacio de nombres para Func<IList<X>, int, IDictionary<Y, IList<Z>>>.

public alias Bar = Func<IList<X>, int, IDictionary<Y, IList<Z>>>; 

entonces podría definir también espacio de nombres de ámbito alias para, por ejemplo, IDictionary<Y, IList<Z>>.

Y si se usa apropiadamente :), hará que el código sea más legible. Ahora, tengo que alinear los tipos genéricos y el código real no es bien legible :(

¿Has encontrado el mismo problema :)? ¿Hay alguna buena razón por la cual no está en C# 3.0? ¿O no hay una buena razón, es solo cuestión de dinero y/o tiempo?

EDITAR: Sé que puedo usar using, pero no tiene un espacio de nombres con ámbito, no tan conveniente para mi caso.

EDIT2: Vea comment by Joren donde sugiere que la tipificación estructural también podría resolver el problema.

+0

No estoy seguro de cuál es el problema con 'using', ya que no define un nuevo tipo, pero ¿no es eso lo que quieres? –

+0

Como escribí, no es un espacio de nombres con ámbito, sino más bien un archivo con ámbito. Necesito usar el alias en los archivos y ensamblajes de cs. –

Respuesta

8

Usted está de suerte; la directiva de uso solo afecta su archivo actual. No hay ningún mecanismo de aliasing del tipo de espacio de nombres.

Esta es una característica solicitada con bastante frecuencia, lo cual son buenos puntos. Pero también es una función de conveniencia "agradable de tener" en lugar de una que realmente agrega mucho poder de representación al lenguaje, lo cual es un punto en contra. Sería bueno hacerlo, pero no está muy alto en la lista de prioridades.

+1

Si no me equivoco, el tipado estructural en los delegados también podría permitirle al compilador lidiar con esta situación específica, aunque de una manera muy diferente.¿Hay alguna posibilidad razonable de que alguna vez se implemente el soporte para el tipado estructural para cosas como los delegados? – Joren

+0

@Joren: Sí, eso resolvería este problema. Creo que la mayoría de la gente ahora se da cuenta de que podría haber sido mejor tener un tipado estructural en los delegados desde el principio, pero ese barco ha navegado. Sería un gran cambio romperlo ahora. Dicho esto, existe un renovado interés en el tipado estructural, por lo que no querría hacer la declaración de que no hay posibilidad de que esto ocurra. –

0

Si lo hace ...

var results = source.Select((x, i) => foo.Bar(x, i)); 

puede averiguar los tipos para usted sin tener que especificar explícitamente.

(Es cierto que esto es más de un trabajo en torno a una solución)

+1

Sí, lo sé :) No responde mi pregunta, pero gracias :) –

Cuestiones relacionadas