Search code examples
c#getter-setter

C# class property with "two types"


I there any way in c# to create a property which will be basically a bool but can be set via string? What I want to achive is simple:

string stringValue = "true";
object.BoolValue = stringValue ;
bool boolValue = object.BoolValue;

My idea was using get; set; but it always crashes on conversion. I can convert that string in object constructor but what if I want to change it later? Do I need a separate method for conversion (it is not only "true"/"false" but in that setter there should be a list of true values and false values and the rest is argument exception)?

Thanks for any ideas on how to achive this.

UPDATE: Code from OPs comment

private bool _readOnly;

public bool ReadOnly {
    get => _readOnly;
    set => _readOnly = Convert.ToBoolean(value);
}

public DeviceProperty(string readOnly) {
    ReadOnly = readOnly;
}

UPDATE: Solution

Down here you can find a solution with explicit conversion which would works just fine in my application. But regarding best practices in programming I created method to set internal boolean to true/false and then can read it normally.

string stringValue = "true";
_ = object.SetBoolValue = stringValue ;
bool boolValue = object.BoolValue;


public bool SetBoolValue(string stringValue)
{
    string[] trueValues = ..........
    string[] falseValues = .........

    if(trueValues contains stringValue)
    {
        BoolValue = true;
        return true;
    }
    if(falseValues contains stringValue)
    {
        BoolValue = false;
        return true;
    }
    return false;
}

Most important for me is a possibility to create logical operation on this boolValue easily so that is the reason I created Set method and not Get method.

UPDATE: Solution 2...

I am not publishing any code here again but just an update that my last statement about storing as bool to have easier access to logical operations on it shown to be wrong. Because "one changes its mind" and the lists of true and false values change. All the time. And also the way you would not expected. Something what was false is now true etc... And the result bool has to be set based on current setup not something from yesterday. So the object remembers string value and have method GetBool() to say if its true or not based on current lists...


Solution

  • You can't modify built-in types but you can create a new type that defines Implicit Operator inside and you can set both string and bool to this type. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/user-defined-conversion-operators

    Also you can define an Explicit operator too, to cast your object to both of types without actually casting.

    public struct MyBoolString
    {
        private bool _value;
    
        public static implicit operator MyBoolString(bool value)
        {
            return new MyBoolString { _value = value };
        }
    
        public static implicit operator bool(MyBoolString value)
        {
            return value._value;
        }
    
        public static implicit operator MyBoolString(string value)
        {
            return new MyBoolString { _value = bool.Parse(value) };
        }
    
        public static implicit operator string(MyBoolString value)
        {
            return value._value.ToString();
        }
    }
    

    Then you can use it like that

    MyBoolString myBoolString = "true";
    myBoolString = true;
    
    bool myBool = myBoolString;
    string myString = myBoolString;
    

    And as a property:

    public MyBoolString Foo { get; set; }
    

    WARNING: This might be not the best practice for your situation. If you create a new type that means you have to handle serialization & deserialization logic of the type. I.E. database providers can't know your custom type or use it in the wrong way. It's not suggested as a best practice if you use the approach to carry data.