Predicados.....

17/05/2007 - 08:09 por Daniel A. Calvin - Cooperator Team | Informe spam
Hola Gente

Primero aclaro, son las dos de la mañana, mis 2 neuronas ya estan un poco
agotadas, asi que si la respuesta es del tipo Pibe lee bien la ayuda antes
de preguntar pavadas!!!!, no me enojo y bienvenida sea(mientras me digan
como arreglarlo ) :))

Tengo una cuestión que me atormenta ( ya lo habarn notado por la
introduccion )
Estoy usando predicados para una clase que hereda de List, invocando los
metodos Find y Exist.

Todo me funciona muy lindo, pero de una forma un poco sucia.

Les muestro:

public class PlanDeCuentas
{
private Cuenta actual;
private CuentaList cl=null;
public PlanDeCuentas()
{
ILazyProvider lazyProvider =
LazyProviderFactory.Get(typeof(Cuenta));
cl = lazyProvider.GetList(typeof(Cuenta), null) as CuentaList;
}

private Boolean existeSubCuenta(Cuenta subCuenta)
{
this.actual = subCuenta;
Boolean b = cl.Exists(existeCuentaPredicado);
this.actual = null;
return b;
}

private Boolean existeCuentaPredicado(Cuenta cuenta)
{
return cuenta.Equals(actual);
}

Lo importante es lo que esta en negrita y en negrita color rojo.
El predicado funciona espectacularmente bien, pero necesito un valor contra
el cual comparar, eso me fuerza en todos los metodos que van invocar un
predicado inicializar un valor de comparación, ya que el parametro definifdo
en el predicado lo pasa el List automaticamente.

En el ejemplo el valor de comparación lo estoy guardando en un objecto
Cuenta que se llama actual. ( cosa fea y chancha a todas luces )
Eso me fuerza a hacer este tipo de cosas:

this.actual = subCuenta;
Boolean b = cl.Exists(existeCuentaPredicado);
this.actual = null;

Se imaginaran mi odio para con ese campo privado.

Como contrapartida lo uso en otros casos en donde me resulta comodo y muy
natural: ( ademas de muy seguro )

public virtual Cuenta[] CuentasImputables
{
get
{
return cl.FindAll(esCuentaImputable).ToArray();
}
}

private Boolean esCuentaImputable(Cuenta cuenta)
{
return cuenta.Imputable.GetValueOrDefault();
}


Aca como verán el uso es muy satisfactorio, digamos que tiene una sintaxis
mucho mas elegante y natural.

Resumiendo, me olvide de leer un capítulo? se puede hacer esto de forma mas
elegante?

Luego de mucho trabajar llegue a este esquema, una clase que reciba en su
constructor, si aplica, el objeto necesario para la comparación:

internal class predicadosPlanDeCuentas
{
private Cuenta cuenta = null;

internal predicadosPlanDeCuentas() { }
internal predicadosPlanDeCuentas(Cuenta cuenta)
{
this.cuenta = cuenta;
}
internal Boolean existeCuenta(Cuenta cuenta)
{
return cuenta.Equals(this.cuenta);
}
internal Boolean esCuentaImputable(Cuenta cuenta)
{
return cuenta.Imputable.GetValueOrDefault();
}
}

Y mi código ahora quedo asi:

public class PlanDeCuentas
{
private CuentaList cl=null;

public PlanDeCuentas()
{
ILazyProvider lazyProvider =
LazyProviderFactory.Get(typeof(Cuenta));
cl = lazyProvider.GetList(typeof(Cuenta), null) as CuentaList;
}

private Boolean existeSubCuenta(Cuenta subCuenta)
{
return cl.Exists(new
predicadosPlanDeCuentas(subCuenta).existeCuenta);
}

public virtual Cuenta[] CuentasImputables
{
get {
return cl.FindAll(new
predicadosPlanDeCuentas().esCuentaImputable).ToArray();
}
}


Esto por supuesto es mucho mas simple de manejar que lo anterior, mucho
menos propenso a mal uso, pero sigue sin convencerme.
( aunque en cierta forma estoy mas conforme )
Hice todo la evolución para que puedan ver los pros y contras que encontre
en mis implementaciones de prueba ( la primera es de terror y esta
totalmente descartada, me sirvio como prueba de concepto digamos...)

Seguramente alguno de ustedes podrá iluminarme, mientras seguire leyendo
sobre el particular. :((

Gracias

Daniel A. Calvin
Cooperator Team Member
http://www.cooperator.com.ar
Microsoft Certified Professional
 

Leer las respuestas

#1 Daniel A. Calvin
17/05/2007 - 14:54 | Informe spam
Hola a todos

En las listas del MUG de Argentina, en donde también mande la pregunta, me
han dado la solución, la pongo a continuación, es simple, me soluciono el
problema y tal vez alguien se encuentre con este problema Tonto y lo
convierta en algo como complejo. ( tal como me paso a mi )

-
Luis Farzati contesto:

Si es que te entiendo bien, por qué no usar un método anónimo, que además en
tu caso creo que tiene un scope más conveniente (ya que sólo lo necesitás
dentro de existeSubCuenta())


private Boolean existeSubCuenta(Cuenta subCuenta)
{

return cl.Exists(delegate(Cuenta item) { return
item.Equals(subCuenta); });

}

Saludos,

Luis
-

Me parecio que valia la pena compartirlo.


Daniel A. Calvin
MCP


"Daniel A. Calvin - Cooperator Team" wrote:

Hola Gente

Primero aclaro, son las dos de la mañana, mis 2 neuronas ya estan un poco
agotadas, asi que si la respuesta es del tipo Pibe lee bien la ayuda antes
de preguntar pavadas!!!!, no me enojo y bienvenida sea(mientras me digan
como arreglarlo ) :))

Tengo una cuestión que me atormenta ( ya lo habarn notado por la
introduccion )
Estoy usando predicados para una clase que hereda de List, invocando los
metodos Find y Exist.

Todo me funciona muy lindo, pero de una forma un poco sucia.

Les muestro:

public class PlanDeCuentas
{
private Cuenta actual;
private CuentaList cl=null;
public PlanDeCuentas()
{
ILazyProvider lazyProvider =
LazyProviderFactory.Get(typeof(Cuenta));
cl = lazyProvider.GetList(typeof(Cuenta), null) as CuentaList;
}

private Boolean existeSubCuenta(Cuenta subCuenta)
{
this.actual = subCuenta;
Boolean b = cl.Exists(existeCuentaPredicado);
this.actual = null;
return b;
}

private Boolean existeCuentaPredicado(Cuenta cuenta)
{
return cuenta.Equals(actual);
}

Lo importante es lo que esta en negrita y en negrita color rojo.
El predicado funciona espectacularmente bien, pero necesito un valor contra
el cual comparar, eso me fuerza en todos los metodos que van invocar un
predicado inicializar un valor de comparación, ya que el parametro definifdo
en el predicado lo pasa el List automaticamente.

En el ejemplo el valor de comparación lo estoy guardando en un objecto
Cuenta que se llama actual. ( cosa fea y chancha a todas luces )
Eso me fuerza a hacer este tipo de cosas:

this.actual = subCuenta;
Boolean b = cl.Exists(existeCuentaPredicado);
this.actual = null;

Se imaginaran mi odio para con ese campo privado.

Como contrapartida lo uso en otros casos en donde me resulta comodo y muy
natural: ( ademas de muy seguro )

public virtual Cuenta[] CuentasImputables
{
get
{
return cl.FindAll(esCuentaImputable).ToArray();
}
}

private Boolean esCuentaImputable(Cuenta cuenta)
{
return cuenta.Imputable.GetValueOrDefault();
}


Aca como verán el uso es muy satisfactorio, digamos que tiene una sintaxis
mucho mas elegante y natural.

Resumiendo, me olvide de leer un capítulo? se puede hacer esto de forma mas
elegante?

Luego de mucho trabajar llegue a este esquema, una clase que reciba en su
constructor, si aplica, el objeto necesario para la comparación:

internal class predicadosPlanDeCuentas
{
private Cuenta cuenta = null;

internal predicadosPlanDeCuentas() { }
internal predicadosPlanDeCuentas(Cuenta cuenta)
{
this.cuenta = cuenta;
}
internal Boolean existeCuenta(Cuenta cuenta)
{
return cuenta.Equals(this.cuenta);
}
internal Boolean esCuentaImputable(Cuenta cuenta)
{
return cuenta.Imputable.GetValueOrDefault();
}
}

Y mi código ahora quedo asi:

public class PlanDeCuentas
{
private CuentaList cl=null;

public PlanDeCuentas()
{
ILazyProvider lazyProvider =
LazyProviderFactory.Get(typeof(Cuenta));
cl = lazyProvider.GetList(typeof(Cuenta), null) as CuentaList;
}

private Boolean existeSubCuenta(Cuenta subCuenta)
{
return cl.Exists(new
predicadosPlanDeCuentas(subCuenta).existeCuenta);
}

public virtual Cuenta[] CuentasImputables
{
get {
return cl.FindAll(new
predicadosPlanDeCuentas().esCuentaImputable).ToArray();
}
}


Esto por supuesto es mucho mas simple de manejar que lo anterior, mucho
menos propenso a mal uso, pero sigue sin convencerme.
( aunque en cierta forma estoy mas conforme )
Hice todo la evolución para que puedan ver los pros y contras que encontre
en mis implementaciones de prueba ( la primera es de terror y esta
totalmente descartada, me sirvio como prueba de concepto digamos...)

Seguramente alguno de ustedes podrá iluminarme, mientras seguire leyendo
sobre el particular. :((

Gracias

Daniel A. Calvin
Cooperator Team Member
http://www.cooperator.com.ar
Microsoft Certified Professional



Preguntas similares