ERROR:
user-defined conversion must convert to or from the enclosing type in:
public static explicit operator E(M value)
{
return value.Value;
}
public static implicit operator M(E value)
{
return new M { Value = value };
}
Example:
BaseModel
public abstract class BaseModel<E, M>
where E : class, new()
where M : BaseModel<E, M>, new()
{
public BaseModel()
{
this.Value = new E();
}
public static explicit operator E(M value)
{
return value.Value;
}
public static implicit operator M(E value)
{
return new M { Value = value };
}
public E Value { get; set; }
public override string ToString()
{
return Value.ToString();
}
}
Usage:
public class Usuario
{
public int PK_USUARIO { get; set; } //IDENTITY(1,1) NOT NULL,
public bool USUA_NR_ATIVO { get; set; } //bit NOT NULL,
}
Model:
[DisplayName("Status")]
[System.ComponentModel.Editor(typeof(bool), typeof(bool))]
public bool Ativo
{
get { return Value.USUA_NR_ATIVO; }
set { Value.USUA_NR_ATIVO = value; }
}
I see what you are trying to do. Unfortunately .NET does not allow to define conversion operators in the base class. They only can convert to the exact type. Either the argument or the return type must exactly match the current class.
So the conversion operator has to be defined in the derived class M
.
Of course, this breaks the DRY principle, but I have no idea how to implement generic conversion operators. I think this is not possible at all because the generic conversion would apply to an infinite number of types in general.
In the first case you could probably live with
public static explicit operator E(BaseModel<E,M> value)
{ return value.Value;
}
But the inverse conversion will not work. This would imply the E
could convert to any type derived from BaseModel<E,M>
. This is probably not what you intended.
However, you would need to define only one of the operators in any derived class if you could live with the generic conversion above. At least this is less DRY.
Some further comment:
You should also know that using where X : new()
is quite slow as it invokes Activator.CreateInstance
which itself uses reflection to call the constructor.
You could avoid this by using a constructor that takes an E
argument and a cached compiled expression to invoke this constructor. This avoids the reflection call for every instance but the first one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With