0

If I have a user-defined type like this, there is some noise when using the type, as you have to add the propertyname Value when assigning or reading the content

public class CharArray
{
    private byte[] _value;

    public CharArray(int length)
    {
        _value = new byte[length];
    }

    public string Value
    {
        get => Encoding.ASCII.GetString(_value);
        set
        {
            if (value.Length > _value.Length)
                throw new Exception($"Max length is {_value.Length} characters");

            _value = Encoding.ASCII.GetBytes(value.PadRight(_value.Length));
        }
    }
}

So usage will be something like this:

CharArray field = new CharArray(10);
field.Value = "Test";
string fieldAsString = field.Value;

Getting rid the Value property when reading the value is pretty easy, by just adding an implicit operator. This will enable users of CharArray to avoid ".Value" when reading the value

    public static implicit operator string(CharArray c)
    {
        return c.Value;
    }

However I have not found a way to avoid the .Value property when assigning a value. Any ideas?

I cannot use a static method, as I need the value given in the constructor. So I guess I am looking for a way to overload the = operator in a non static method. Is that possible in C# ?

Torben Nielsen
  • 663
  • 1
  • 8
  • 21
  • Clearly you know that implicit conversion operators exist, so why not just add another implicit operator from `string` to `CharArray`? – Sweeper Aug 21 '21 at 12:24
  • @Sweeper: Note that my CharArray takes a value in the constructor. So a static implicit operator will loose this value – Torben Nielsen Aug 21 '21 at 12:27
  • 2
    I just noticed that. The initial length for your byte array is rather nonsensical here. A static implicit operator is _not_ the reason why you "lose" this value. You already lost that value when you do `_value = Encoding.ASCII.GetBytes(...)`. `GetBytes` doesn't care about the length of `_value` before the assignment. It returns an array with just enough bytes to encode the string, _not necessarily_ the same length as `_value` at all. – Sweeper Aug 21 '21 at 12:31
  • @sweeper: Notice that I have a PadRight added to maintain the same length always – Torben Nielsen Aug 21 '21 at 12:33
  • @Torben Nielsen: Note, that UTF-8 string can have *two bytes* characters, that's why `Length` in *characters* is less then Length in *bytes*: `value.PadRight(_value.Length).Length <= _value.Length` – Dmitry Bychenko Aug 21 '21 at 12:36
  • @TorbenNielsen Maybe also fix the title of your question. It's not consistent with what you're asking at the bottom of the question. – Nenad Aug 21 '21 at 12:38
  • Why do you use the underlying `byte[]`? Why not just keep it simpler just using a string as a field? If what you want is constant string length... – SnowGroomer Aug 21 '21 at 12:44
  • 1
    @SnowGroomer Did I oversimplify my sample code? The real code is for type-definitions of structs defined in languages such as COBOL or C, where strings are fixed size char-arrays. The length of such a fized size char-array is given in the constructor. – Torben Nielsen Aug 21 '21 at 12:51
  • 2
    See the list of overloadable (and non-overloadable) operators here: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/operator-overloading#overloadable-operators I'm surprised no one has posted this yet. It's clear which group `=` belongs to. – Sweeper Aug 21 '21 at 12:56
  • If it is for struct, then property code shoud be in the parent `struct` instead of using properties of type `CharArray`. Those property would be of type `string`and would use `CharArray` for the data and you would need `.Value` only twice per structure while defining the corresponding `string` property. – Phil1970 Aug 21 '21 at 13:08
  • Does this answer your question? [Is it possible to override assignment "=" in C#](https://stackoverflow.com/questions/18782218/is-it-possible-to-override-assignment-in-c-sharp) and [Why can '=' not be overloaded in C#?](https://stackoverflow.com/questions/599367/why-can-not-be-overloaded-in-c) and [C# mimic overridding the assignment operator (=)](https://stackoverflow.com/questions/644854/c-sharp-mimic-overridding-the-assignment-operator) and [Assignment operator in C#](https://stackoverflow.com/questions/41385447/assignment-operator-in-c-sharp) –  Aug 21 '21 at 13:11
  • 1
    @Olivier Rogier: Yes it does. It is not what I was hoping for, but at least it has an explanation of why it is not possible. Thanks. (You want to add that as an answer, not just a comment?) – Torben Nielsen Aug 21 '21 at 13:31

1 Answers1

2

You can make implicit conversion in other direction string -> CharArray:

public static implicit operator CharArray(string s)
{
    return new CharArray(s.Length){ Value = s };
}

Then this works:

CharArray field = new CharArray(10);
field = "Test"; // all good!
string fieldAsString = field;
Nenad
  • 24,809
  • 11
  • 75
  • 93
  • I would loose the length given in the original constructor (i.e. the value 10) – Torben Nielsen Aug 21 '21 at 12:29
  • Then you're trying to override `.Value =`, not just `=` operator, as you stated. That's not possible. – Nenad Aug 21 '21 at 12:31
  • 1
    For anyone looking for this, the reason why it is not possible is given here https://stackoverflow.com/questions/18782218/is-it-possible-to-override-assignment-in-c-sharp: – Torben Nielsen Aug 21 '21 at 13:36