Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9084375
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T20:59:00+00:00 2026-06-16T20:59:00+00:00

In this thread How to get null instead of the KeyNotFoundException accessing Dictionary value

  • 0

In this thread

How to get null instead of the KeyNotFoundException accessing Dictionary value by key?

in my own answer I used explicit interface implementation to change the basic dictionary indexer behaviour not to throw KeyNotFoundException if the key was not present in the dictionary (since it was convinient for me to obtain null in such a case right inline).

Here it is:

public interface INullValueDictionary<T, U>
    where U : class
{
    U this[T key] { get; }
}

public class NullValueDictionary<T, U> : Dictionary<T, U>, INullValueDictionary<T, U>
    where U : class
{
    U INullValueDictionary<T, U>.this[T key]
    {
        get
        {
            if (ContainsKey(key))
                return this[key];
            else
                return null;
        }
    }
}

Since in a real application I had a list of dictionaries, I needed a way to access the dictionaries from the collection as an interface. I used simple int indexer to acess each element of the list.

var list = new List<NullValueDictionary<string, string>>();
int index = 0;
//...
list[index]["somekey"] = "somevalue";

The easiest thing was to do something like this:

var idict = (INullValueDictionary<string, string>)list[index];
string value = idict["somekey"];

The question raised when I decided to try to use covariance feature to have a collection of interfaces to use instead. So I needed an interface with covariant type parameter for the cast to work. The 1st thing that came to my mind was IEnumerable<T>, so the code would look like this:

IEnumerable<INullValueDictionary<string, string>> ilist = list;
string value = ilist.ElementAt(index)["somekey"];

Not that nice at all, besides ElementAt instead of an indexer is way worse.
The indexer for List<T> is defined in IList<T>, and T there is not covariant.

What was I to do? I decided to write my own:

public interface IIndexedEnumerable<out T>
{
    T this[int index] { get; }
}

public class ExtendedList<T> : List<T>, IIndexedEnumerable<T>
{

}

Well, few lines of code (I don’t even need to write anything in ExtendedList<T>), and it works as I wanted:

var elist = new ExtendedList<NullValueDictionary<string, string>>();
IIndexedEnumerable<INullValueDictionary<string, string>> ielist = elist;
int index = 0;
//...
elist[index]["somekey"] = "somevalue";
string value = ielist[index]["somekey"];

Finally the question: can this covariant cast be somehow achieved without creating an extra collection?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T20:59:02+00:00Added an answer on June 16, 2026 at 8:59 pm

    You can try use IReadOnlyList<T>, which is implemented by List<T>.

    Note that I’ve added one instance of NullValueDictionary<string, string> to List, so that you won’t get ArgumentOutOfRangeException at elist[index] line.

    IReadOnlyList<NullValueDictionary<string, string>> elist = new List<NullValueDictionary<string, string>>
                                                                        { 
                                                                            new NullValueDictionary<string, string>() 
                                                                        };
    IReadOnlyList<INullValueDictionary<string, string>> ielist = elist;
    
    int index = 0;
    //...
    elist[index]["somekey"] = "somevalue";
    string value = elist[index]["somekey"];
    

    Edit: I’ve searched for covariant interfaces and collections with indexes prior to .NET 4.5, but found none. Still I think there are a little bit easier solution, than to create separate interface – just to cast one collection to another.

    List<INullValueDictionary<string, string>> ielist = elist.Cast<INullValueDictionary<string, string>>().ToList();
    

    Or use covariance gained from arrays

    INullValueDictionary<string, string>[] ielist = elist.ToArray()
    

    LINQ has some optimization that work on whole type compatibility, so you won’t iterate over sequence if those types are compatible.

    Cast implementation taken from MONO Linq

    public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
    {
        var actual = source as IEnumerable<TResult>;
        if (actual != null)
            return actual;
    
        return CreateCastIterator<TResult> (source);
    }
    

    Note that I have changed INullValueDictionary<T, U> interface to contain set in the property so that ielist[index]["somekey"] = "somevalue"; will work.

    public interface INullValueDictionary<T, U> where U : class
    {
        U this[T key] { get; set; }
    }
    

    But again – if creating a new Interface and class is ok for you and you don’t want to mess around with casts everywhere – I think it is a good solution, if you have considered at the constraints, it gives.

    In search of covariance in mscorlib

    This probably won’t be interesting to you, but I’ve just wanted to find out what Types are covariant in mscorlib assembly. By running next script I received only 17 types are covariant, 9 of which are Funcs. I have omitted IsCovariant implementation, because this answer is too long even without it

    typeof(int).Assembly.GetTypes()
                        .Where(type => type.IsGenericType)
                        .Where(type=>type.GetGenericArguments().Any(IsCovariant))
                        .Select(type => type.Name)
                        .Dump();
    
    //Converter`2 
    //IEnumerator`1 
    //IEnumerable`1 
    //IReadOnlyCollection`1 
    //IReadOnlyList`1 
    //IObservable`1 
    //Indexer_Get_Delegate`1 
    //GetEnumerator_Delegate`1 
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I saw this thread here but didnt get any answer to my thoughts. for
UPDATE 1/31/10 : Since this thread continues to get a lot of views...I am
I want to get the user mail address, as shown in this thread :
I recevie 0 errors but I get this in the console: >Exception in thread
In this thread , it is described how you can fetch the selected value
I have been trying to get it to work using this thread but can't
This thread didn't helped me. If I use $class_vars = get_class_vars(get_class($this)); foreach ($class_vars as
Is this thread safe? private static bool close_thread_running = false; public static void StartBrowserCleaning()
Following this thread, I tried to upload a file on the server. If I
This question is based on this thread . Is [---] a comment in Git

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.