usando tipos restricciones permiten genericos generico genericas ejemplos declaraciones constructores colecciones clases abstractas c# .net generics constraints

c# - tipos - ¿Por qué no podemos usar clases selladas como restricciones genéricas?



tipos de genericos (4)

¿Puede adivinar cuál es la razón para no permitir clases selladas para restricciones de tipo en genéricos? Solo tengo una explicación para dar oportunidad de usar restricciones desnudas.


¿Estás hablando de algo como esto?

class NonSealedClass { } class Test<T> where T : NonSealedClass { }

Porque es perfectamente legal.


Si la clase está sellada no se puede heredar. Si no se puede heredar, sería el único tipo válido para el argumento de tipo genérico [suponiendo que se permita que sea un argumento de tipo]. Si es el único argumento de tipo genérico, ¡entonces no tiene sentido hacerlo genérico! Simplemente puede codificar contra el tipo en la clase no genérica.

Aquí hay un código para esto.

public class A { public A() { } } public sealed class B : A { public B() { } } public class C<T> where T : B { public C() { } }

Esto dará un error de compilación: ''B'' no es una restricción válida. Un tipo utilizado como restricción debe ser una interfaz, una clase no sellada o un parámetro de tipo.

Además de esto, tampoco puede tener una clase estática como restricción de tipo genérica. La razón es simple. Las clases estáticas se marcan como abstractas y se sellan en la IL compilada que no puede ser instanciada ni heredada.

Aquí está el código para esto.

public class D<T> where T : X { public D() { } } public static class X { }

Esto dará error de compilación: ''X'': las clases estáticas no se pueden usar como restricciones.


Sinceramente, no entiendo muy bien el punto.

Como este .__ curioso_geek señala en su respuesta , una clase sellada no puede ser heredada y, por lo tanto, usar una como una restricción puede parecer absurda.

Pero no hay garantía de que una clase sellada nunca sea "abierta", es decir, que el desarrollador pueda reorganizar su implementación para que sea más fácil de heredar y luego remueva el modificador sealed de la definición de la clase (o simplemente elimine la palabra clave sealed sin ninguna razón en absoluto).

Sé que muchos desarrolladores realmente alientan esta práctica: no eliminar la palabra clave sealed per se, sino agregar la palabra clave sealed generosa y solo respaldar la herencia cuando la decisión de hacerlo se toma explícitamente (y en este punto, sí, eliminar el sealed palabra clave).

Así que no estoy seguro de por qué no podía usar el tipo de una clase sellada como una restricción genérica. Después de todo, siempre se puede usar el tipo de una clase que simplemente no tiene clases derivadas, aunque no esté sellada. Los dos escenarios no me parecen tan diferentes.

Aunque probablemente me esté perdiendo algo. Estoy seguro de que Eric Lippert podría dar una explicación bastante asesina.


Una restricción simple es cuando un tipo genérico se hereda de otro, por ejemplo,

where X:Y

Un parámetro genérico deriva de otro parámetro genérico

class Foo<T> { Foo<S> SubsetFoo<S>() where S : T { } }

Así que la clase no puede ser sellada.

También puede heredar de los genéricos de la manera normal, por lo que no querría sellarlos.