0

Based on my Understanding interfaces are just protocol and do not have any implementation.

I'm trying to understand the following code:

This code works

  Exception ex = new Exception();
  ex.Data.Add("1", "One");

Because Data is a property of type ListDictioaryInternal(as shown by intelisence)) which implements IDictionary.

However, if you right-click on Data and go to the definition you see it is defined as:

public virtual IDictionary Data { get; }

Why Data is not defined as ListDictioaryInternal?

Llazar
  • 3,167
  • 3
  • 17
  • 24
  • 1
    By defining a property with an interface it allows you to set it to anything that implements that interface without breaking any code that currently uses it. – juharr Oct 25 '18 at 13:36
  • Good point. I was also thinking about this, so can Data be set to something other than ListDictioaryInternal? –  Oct 25 '18 at 13:38
  • Aslo why intelisense aways show it as ListDictioaryInternal –  Oct 25 '18 at 13:38
  • 1
    If MS decided to change it to be backed by something else they could without breaking code (at least not breaking any code that doesn't cast it) – juharr Oct 25 '18 at 13:39
  • 5
    It is the debugger who tells you that the object in the Data property is of type ListDictioaryInternal (this tooltip you see is not IntelliSense, it is information provided by the debugger . If you end your debugging session and let IntelliSense tell you the type of the Data property, it will tell you IDictionary...) –  Oct 25 '18 at 13:39
  • 4
    It's worth noting that that `Data` property is declared `virtual`, so that means that anyone who defines their own exception class can override that property and return an object of a type other than `ListDictionaryInternal` if they want, as long as it implements `IDictionary`. – jmcilhinney Oct 25 '18 at 13:48
  • Intellisense shows you the actual run-time type of the object rather than the type of the property returning that object. – jmcilhinney Oct 25 '18 at 13:48
  • Perfect! Now, this explains it all! –  Oct 25 '18 at 13:49
  • Post this as an answer. –  Oct 25 '18 at 13:50
  • post "It's worth noting that that Data property is declared virtual, so that means that anyone who defines their own exception class can override that property and return an object of a type other than ListDictionaryInternal if they want, as long as it implements IDictionary" as answer –  Oct 25 '18 at 13:51
  • @ elgonzo nice point! –  Oct 25 '18 at 13:57

2 Answers2

3

The Exception class defines property Data which is of type IDictionary. This means that any object that implements that interface can be returned by the getter. In fact, if you dig into the definition, you will see this explained in the comments:

// Summary:
//     Gets a collection of key/value pairs that provide additional user-defined information
//     about the exception.
//
// Returns:
//     An object that implements the System.Collections.IDictionary interface and contains
//     a collection of user-defined key/value pairs. The default is an empty collection.
public virtual IDictionary Data { get; }

It looks like the internal implementation of the class uses System.Collections.ListDictionaryInternal as the object that is actually used. If you look at the source code for that class, you will find that it implements the interface in question:

internal class ListDictionaryInternal: IDictionary 
{
    //...
}

So the interface represents a contract of what an object can do. The actual object returned is a concrete class that implements the interface.

JuanR
  • 7,405
  • 1
  • 19
  • 30
  • 1
    Also worth mentioning, you can implement an interface explicitly. By doing so the functions are not accessible directly on the class but only trough the interface. This also has the effect that you can implement two interfaces with the same function defined in one class but have that function do different things depending on which interface is used. :-) – Magnus Oct 25 '18 at 13:52
  • @Magnus: Nice comment. Thank you for adding. I have on occasion used interfaces in this manner. It's not intuitive but it has its uses. – JuanR Oct 25 '18 at 14:02
2

Because ListDictionaryInternal implements IDictionary, so IDictionary is used in compliance with abstraction.

Guy
  • 46,488
  • 10
  • 44
  • 88
  • @BTFman Yes, you can also see it in the comment `Returns: An object that implements the System.Collections.IDictionary interface and contains a collection of user-defined key/value pairs. The default is an empty collection.` – Guy Oct 25 '18 at 13:45
  • @BTFman This is part of OOP abstraction, program to an interface. Hav a look at this thread https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface – Guy Oct 25 '18 at 13:50