Domanda

I have this class:

public struct Field<T>
{
    public Field(int ordinal, int number)
        : this(ordinal, number, default(T))
    {

    }

    public Field(int ordinal, int number, T value)
        : this()
    {
        Ordinal = ordinal;
        Number = number;
        Value = value;
    }

    public int Ordinal
    {
        get;
        private set;
    }

    public int Number
    {
        get;
        private set;
    }

    public T Value
    {
        get;
        private set;
    }

    public static implicit operator Field<T>(T value)
    {
        Field<T> sarsField = new Field<T>();
        sarsField.Value = value;
        return sarsField;
    }

    public static implicit operator T(Field<T> value)
    {
        return value.Value;
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}

I use it as follows:

    // Declare field
    Field<DateTime> dateOfBirth = new Field<DateTime>(5, 25);

    // Set value
    dateOfBirth = DateTime.Today;

Problem is when i assign a DateTime to dateOfBirth it constructs a new Field, but looses the original values for Ordinal and Number. How do i change only the Value property when doing an implicit assignment? Is this possible?

If i made the setter public for Value, i could do this:

    // Set value
    dateOfBirth.Value = DateTime.Today;

Achieves the desired result of setting only the Value, retaining Ordinal and Number. However, i would really like to do this implicitly. There are a number of places where i would like to replace the Type with Field<Type>. Hence, i am looking for an implicit solution.

È stato utile?

Soluzione

You can't. Assignment overwrites the original variable; it doesn't allow you to just overwrite one property of the variable and leave the rest alone. Also, struct's are supposed to be immutable, so modifying just the Value property, in any way, shouldn't be allowed. If you really want to allow this, I'd recommend using a class instead of a struct, and making the Value setter public.

However, if you want to keep it as a struct, I'd recommend something like this instead:

public Field<T> WithValue(T value)
{
    return new Field<T>(this.Ordinal, this.Number, value);
}

And then call it like this:

dateOfBirth = dateOfBirth.WithValue(DateTime.Today);

Also note, I'd strongly recommend making the operator T explicit, because it discards the Ordinal and Numeric values. See this note from MSDN:

If a conversion operation can cause exceptions or lose information, you should mark it explicit.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top