I have a property where I want to convert the values systematically and I have a very large set of properties, so rather than have the following:
class myClass
{
private Double _Length;
public Double Length { get { return convert(_Length); } set { _Length = convertBack(value); }}
private Double _Height;
public Double Height{ get { return convert(_Height); } set { _Height= convertBack(value); }}
private Double _Width;
public Double Width{ get { return convert(_Width); } set { _Width= convertBack(value); }}
...
Double convert(Double base_value) { do work to return converted_value; }
Double unconvert(Double converted_value) { to work to return base_value; }
}
I would like to do something like this to reduce code pollution and redundancy
class myBaseClass
{
class DoublePropertyConverter extends Property
{
public Double get { return convert(this); }
public Double set { this = unconvert(value); }
}
Double convert(Double base_value) { do work to return converted_value; }
Double unconvert(Double converted_value) { to work to return base_value; }
}
class myClass : public myBaseClass
{
[DoublePropertyConverter]
public Double Length { get; set;}
[DoublePropertyConverter]
public Double Height{ get; set;}
[DoublePropertyConverter]
public Double Width{ get; set;}
...
}
Is this, or something like it, at all possible?
There's no way to "extend a property" in the way you're describing, no.
But it's easy enough to create a new type which represents conversions from and two some other value. Types like DateTime
and TimeSpan
are all just wrappers around a long
that handle conversions to different semantic values for you, for example. Honestly it sounds like you should have a new type, because you've got a value that a consumer wants to treat in one way, but that is actually represented in memory as something else, and types are great at accomplishing just that in many situations that goes beyond the scope of getting and setting property values.
public class Foo
{
public Foo(double value)
{
underlyingValue = FromDouble(value);
}
private readonly object underlyingValue;
public double Value => ToDouble(underlyingValue);
public static implicit operator double(Foo foo) => ToDouble(foo.underlyingValue);
public static implicit operator Foo(double value) => new Foo(value);
private static double ToDouble(object underlyingVvalue)
{
throw new NotImplementedException();
}
private static object FromDouble(double value)
{
throw new NotImplementedException();
}
}
The underlying field in the type can be whatever you want that you're converting to/from, and you can then define your conversion logic in just one place.