Search code examples
c#genericsreturn-type

Can I return a different type from a function in a generic class depending on if the generic type used for the class is a value or a reference type?


I want to return a Nullable<Value> from a function in a generic class if Value is a value type, and just 'Value' if value is already a reference type.

I've been trying to work with where clauses to achieve this, but I can't seem to use a where class on a non-generic function, even in a generic class.

    public class HashTable<Key, Value>
    {
        private List<ValueSlot> valueSlots = new List<ValueSlot>();

        private struct ValueSlot
        {
            public bool hasValue;
            public List<KeyValuePair<Key, Value>> values;
        }

        //...

        public Nullable<Value> TryGetValue(Key key) where Value : struct
        {
            (bool result, Value value) = TryGetValue(valueSlots, key);

            if (result == true)
            {
                Nullable<Value> myVal = value;
                return myVal;
            }
            else
            {
                return null;
            }
        }

        public Value TryGetValue(Key key) where Value : class
        {
            (bool result, Value value) = TryGetValue(valueSlots, key);

            return result == true ? value : (Value)null;
        }

        private (bool, Value) TryGetValue(List<ValueSlot> valueSlots, Key key)
        {
            //...
        }

        //...
    }

Unfortunately, this doesn't compile an generates a bunch of errors. I would rather not resort to returning tuples out from the class. Is there a simple way to make this approach work that I am missing? I've been trying to get this to work for nearly a week now...


Solution

  • Polymorphism by return type is not supported by C# yet. Generic type constraint is a hint to the compiler and not making method signatures different.