2009-03-20 13 views
5

Estoy tratando de crear un formulario que anime algo mientras se procesa una tarea en particular (pasado como un delegado al constructor). Está funcionando bien, pero el problema que tengo es que no puedo instanciar una copia de mi clase genérica si el método particular que deseo realizar tiene un tipo de vacío devuelto.pasando el vacío a una clase genérica

Entiendo que esto es por diseño y todo, pero me pregunto si hay una solución conocida para situaciones como esta.

Si se ayuda a todos mis ventanas formulario se ve como tal (que se corta por razones de brevedad):

public partial class operatingWindow<T> : Form 
{ 
    public delegate T Operation(); 
    private Operation m_Operation; 

    private T m_ReturnValue; 
    public T ValueReturned { get { return m_ReturnValue; } } 

    public operatingWindow(Operation operation) { /*...*/ } 
} 

Y lo llamo gustan:

operatingWindow<int> processing = new operatingWindow<int>(new operatingWindow<int>.Operation(this.doStuff)); 
processing.ShowDialog(); 

// ... 
private int doStuff() 
{ 
    Thread.Sleep(3000); 

    return 0; 
} 

Respuesta

4

Me gustaría repensar un poco su diseño.

Si implementó el procesamiento en una clase base, podría crear una subclase con 2 alternativas que serían casi intercambiables.

La primera podría ser como la suya, donde se necesita una operación que devuelve un valor. (Sin embargo, lo retrabajaría para usar Func<T> en lugar de tener su propio tipo de delegado.

El segundo solo podría tomar una Acción simple y no proporcionar un valor de retorno. Ambos podrían usar las mismas rutinas de animación/visualización/etc. .. pero proporcionan una manera diferente de trabajar también podría pasar esto a otros métodos que utilizan la clase base, lo que proporcionaría una gran flexibilidad

con este enfoque, se podría llamar esto como:

private void DoSleep() 
{ 
    Thread.CurrentThread.Sleep(5000); 
} 
private int ReturnSleep() 
{ 
    Thread.CurrentThread.Sleep(5000); 
    return 5000; 
} 
... 
{ 
    var actionWindow = new OperatingWindowAction(this.DoSleep); 
    actionWindow.Execute(); 
    var funcWindow = new OperatingWindowFunc<int>(this.ReturnSleep); 
    funcWindow.Execute(); 
    int result = funcWindow.Result; 
} 

Esto se vería algo así como:

public abstract partial class OperatingWindowBase : Form 
{ 
    public void Execute() 
    { 
     // call this.OnExecute(); asyncronously so you can animate 
    } 
    protected abstract void OnExecute(); 
} 

public class OperatingWindowFunc<T> : OperatingWindowBase 
{ 
    Func<T> operation; 
    public T Result { get; private set; } 
    public OperatingWindowFunc<T>(Func<T> operation) 
    { 
     this.operation = operation; 
    } 
    protected override OnExecute() 
    { 
     this.Result = operation(); 
    } 
} 

public class OperatingWindowAction 
{ 
    Action operation; 
    public OperatingWindow(Action operation) 
    { 
     this.operation = operation; 
    } 
    protected override OnExecute() 
    { 
     operation(); 
    } 
} 
6

No, usted tendrá que crear una sobrecarga para hacer eso.

p. Ej.

public operatingWindow(Action action) 
{ 
    m_Operation=() => { action(); return null; } 
} 

también que no es necesario definir su propio delegado, puede utilizar Func<T> y Acción.

Cuestiones relacionadas