Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is ambiguous about this derived interface getter?

I am looking to add these interfaces:

public interface IIndexGettable<TKey, TValue>
{
    TValue this[TKey key]{ get; }
}

public interface IIndexSettable<TKey, TValue>
{
    TValue this[TKey key]{ set; }
}

public interface IIndexable<TKey, TValue> : IIndexGettable<TKey, TValue>, IIndexSettable<TKey, TValue>
{   
  // new TValue this[TKey key]{ get; set; } // as suggested by SO question 1791359 this will "fix" the issue.
}

When I then try to use an IIndexable's getter, I get the following compiler error:

The call is ambiguous between the following methods or properties: 'IIndexGettalbe<TKey, TValue>.this[Tkey]' and 'IIndexSettable<TKey, TValue>.this[TKey]'

Here is the code I was running:

public static class IIndexableExtensions
 {
    public static Nullable<TValue> AsNullableStruct<TKey, TValue>(this IIndexable<TKey, object> reader, TKey keyName) where TValue : struct
    {
        if (reader[keyName] == DBNull.Value) // error is on this line.
        {
            return null;
        }
        else
        {
            return (TValue)reader[keyName];
        }
    }   
 }

Shouldn't it unambiguously inherit the getter from the IIndexGettable and the setter from the IIndexSettable?

By the way, I am not trying to have this sound inflammatory towards the language design. I am sure there is a good reason behind this, my goal is to understand what the reason is to get a better understanding of the language.

like image 538
user420667 Avatar asked Oct 22 '15 17:10

user420667


1 Answers

Tried the below code, and it works fine. What is the scenario of your error? What's not in this code?

class Program
    {
        static void Main(string[] args)
        {
            Foo<int, string> foo = new Foo<int, string>();
            foo.dict.Add(1, "a");
            foo.dict.Add(2, "b");
            Console.WriteLine(((IIndexGettable<int, string>)foo)[1]);
            ((IIndexSettable<int, string>)foo)[3] = "c";
            Console.WriteLine(foo[3]);
            Console.ReadLine();
        }
    }

    public interface IIndexGettable<TKey, TValue>
    {
        TValue this[TKey key] { get; }
    }

    public interface IIndexSettable<TKey, TValue>
    {
        TValue this[TKey key] { set; }
    }

    public interface IIndexable<TKey, TValue> : IIndexGettable<TKey, TValue>, IIndexSettable<TKey, TValue>
    {

    }

    public class Foo<TKey, TValue> : IIndexable<TKey, TValue>
    {
        public Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>();
        public TValue this[TKey key]
        {
            get
            {
                return dict[key];
            }

            set
            {
                dict[key] = value;
            }
        }

    }
like image 99
singsuyash Avatar answered Sep 23 '22 04:09

singsuyash