How to make a type that for all intents and purposes act like a string, since I cannot inherit from a string

Viewed 55

I like types. Like to be able to specify meaning to a string or int etc)

A string or an int can be almost anything,

I enjoy giving a string a meaningful type. I also prefer that when you have a longish function call. That way people who use it wont pass in strings in the wrong order.

I often use strings as parameters and I want "MembersName" as a Type derived from string.

I can easily do something like MembersName.Value where string is a property of another class. I would rather derive my class from String but that is not possible since it is sealed.

I have looked at the System.String source and thought about taking it out use it to make my own String type, but I decided against it.

Then I started creating my own stand in base class that I could derive my other string-like types from StringBase (realy good name).

I am working on implementing IEquatable, ICloneable, IComparable, IComparable, IConvertible, IEquatable, IEnumerable

In the base type to make it appear as much like a string as possible.

I would prefer to be able to Membername == "Phil Collins".

It is also desirable to mimick other features of String.

Is this the right path? and does anyone have a version of it written already? I figure the need must have come up before from someone else?
I tried hunting Google and GitHub without much luck so far.

Am I going down the right path? Or is what I am trying to do nearly impossible?

1 Answers

I think this can be a good design as it provides type safety for different types of strings (enabling better support for overloading methods, refactoring etc.).

I dug up something from an old project that might get you started at least.

In this case I had a strongly typed UserId functioning (almost) as a string.

Maybe if you complete this with implicit operators as 'GuruStron' suggested you will have something to work on, although if I remember correctly I chose not to provide implicit operators as it made the type "less type safe".

public struct UserId : IStringIdentifier, IEquatable<UserId>
{
    public UserId(string id) : this() => Value = id;

    public string Value { get; set; }

    public static bool operator ==(UserId id1, UserId id2) 
        => id1.Value == id2.Value;

    public static bool operator !=(UserId id1, UserId id2) 
        => id1.Value != id2.Value;

    public override bool Equals(object obj)
    {
        if (obj is UserId other)
            return Equals(other);

        return false;
    }

    public bool Equals(UserId other) => Value.Equals(other.Value);
    public override string ToString() => Value;
    public override int GetHashCode() => Value.GetHashCode();
}

Edit: Cleaned it up a bit.

Related