2011-08-12 12 views
5

Estoy creando una aplicación de rendimiento crítico que implementa la manipulación de imágenes. Estoy usando algunos punteros de píxeles usando mi estructura llamada Pixel para hacer algo de procesamiento. Tengo muchas partes de código que iteran sobre los datos de mapa de bits, y en aras de la reutilización y modularidad del código, estoy diseñando un método que tomará una acción y la aplicará a todos los píxeles de la imagen (como un mapa función). Sin embargo, cuando escribo Action<Pixel*>, Visual Studio se queja del código que dice que el tipo Pixel* no se puede usar como argumento de tipo. Toda la clase está en un contexto unsafe y estoy usando Pixel punteros en todas partes, pero simplemente no puedo usar un puntero de píxeles como clase de plantilla de Acción.Uso de la acción <PointerClass *> como argumento

Puedo usar Action<IntPtr> pero tendré que convertirlo en los punteros apropiados dentro del cuerpo del método en CUALQUIER iteración, lo que mataría a la idea de ser "crítico para el rendimiento".

+0

¿Aparece un mensaje de error exacto? –

+0

'El tipo 'Tools.Imaging.Pixel *' no se puede utilizar como argumento de tipo ' –

+0

¿Por qué no simplemente' Acción ' –

Respuesta

8

Parece que nada le obliga a usar Action<T>, por lo que puede crear su propio tipo de delegado. Yo no encontrar una manera de hacer esto de una manera genérica, pero esto funciona:

unsafe delegate void PixelAction(Pixel* ptr); 

Tenga en cuenta que si esto es realmente el rendimiento crítico, la invocación de un delegado es más lento que acaba de llamar a un método directamente. Quizás otra forma podría ser mejor, como duplicar código (si eso funciona en su caso) o generación de código, ya sea en tiempo de compilación o en tiempo de ejecución utilizando Reflection.Emit o CodeDOM.

+0

sí. esta respuesta me hizo pensar lo mismo :) trabajar con 'Action's me hizo olvidar por completo a los delegados regulares, intentaré implementar este. –

1

Los tipos de puntero no son clases, por lo que no se pueden usar como argumentos de tipo genérico.

Creo que su único enfoque sería definir la Acción <IntPtr>, y emitir según sea necesario en ambos lados. No creo que el rendimiento sea tan malo como piensas al compilar con optimizaciones.

EDIT: Resulta que el siguiente no funciona (CS0208)

O eso, o en lugar de utilizar Acción <T> definir su propio tipo de delegado podría funcionar:

delegate void PointerAction<T>(T* ptr); 

+1

Eso no parece funcionar: "Los punteros y los almacenamientos intermedios de tamaño fijo solo se pueden utilizar en un contexto inseguro". Si agrego 'inseguro', entonces:" No puedo tomar la dirección de, obtener el tamaño de, o declarar un puntero a un tipo administrado ('T') ". – svick

Cuestiones relacionadas