2012-08-11 11 views
5

Retroceder en el tiempo cuando .NET Reflector era libre Lo usé para boquear el código de .NET framework. Me vino a la atención que la mayoría de las colecciones en .NET 2.0 (creo que esto es aplicable para las versiones actuales también) utilizar el siguiente mecanismo para reconocer modificaciones de recogida durante bucles:Modificar una colección .NET incorporada int.MaxValue veces y más - error potencial de desbordamiento

public class SomeCollection<T> 
{ 
    internal int version = 0; 

    // code skipped for brevity 

    public void Add(T item) 
    { 
     version++; 

     // add item logic ... 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return new SomeCollectionEnumerator<T>(this); 
    } 
} 

public class SomeCollectionEnumerator<T> : IEnumerator<T> 
{ 
    private SomeCollection<T> collection; 
    private int version; 

    public SomeCollectionEnumerator(SomeCollection<T> collection) 
    { 
     this.version = collection.version; 
     this.collection = collection; 
    } 

    public bool MoveNext() 
    { 
     if (this.version != this.collection.version) 
     { 
      // collection was modified while iterated over 
      throw SomeException(...); 
     } 
     // iteration logic here... 
    } 
} 

Ahora imagine el caso hipotético de una carrera de larga aplicación (un servicio web muy utilizado que debe tener un tiempo de inactividad mínimo y debe ser estable y confiable) que mantiene en memoria una instancia de colección determinada (uno de los tipos de colección integrados en .NET framework) en la memoria mientras se ejecuta. La colección se modifica con la frecuencia suficiente para que las modificaciones int.MaxValue puedan suceder. Existe el riesgo de que la línea version++ en cada método de modificación de la colección arroje una excepción de desbordamiento (suponiendo que las comprobaciones de desbordamiento no estén globalmente deshabilitadas).

Debo admitir que tengo memorias débiles de los detalles del código reflejado, pero no recuerdo el uso de unckecked bloques alrededor de version++ operaciones. ¿Significa esto que los tipos de colección incorporados en .NET no son adecuados para el propósito de este escenario de aplicación de larga duración? Solo por curiosidad, ¿alguien ha encontrado un escenario de la vida real donde esto realmente podría suceder?

+1

dotPeek (http://www.jetbrains.com/decompiler/) es un decompilador libre y bueno, en caso de que el La historia del reflector le dejó un sabor amargo en la boca. – spender

+1

También el código fuente de BCL (y la mayoría de las demás bibliotecas .NET de MSFT) se comparte y está disponible en http://referencesource.microsoft.com/netframework.aspx –

+1

@spender gracias, para mí la sensación es más como estar cegado en vez de tener un sabor agrio, pero supongo que ambos queremos decir lo mismo. Otra cosa útil para aprender hoy: una nueva herramienta descompiladora, incluso de jetbrains –

Respuesta

4

No, porque el compilador de C# hace que la aritmética de enteros unchecked by default. (Esto incluye el BCL compilado.)

+0

Bien, no sabía eso. Supongo que entonces podría aventurarme a escribir una aplicación que haría las modificaciones de la colección 'int.MaxValue' un día :) Gracias por la rápida respuesta. –

Cuestiones relacionadas