Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Item" property along with indexer

I've read the answers for Class with indexer and property named "Item", but they do not explain why can I have a class with multiple indexers, all of them creating Item property and get_Item/set_Item methods (of course working well, as they are different overloads), but I cannot have an explicit Item property.

Consider the code:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
        }

        public int this[string val]
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public string this[int val] //this is valid
        {
            get
            {
                return string.Empty;
            }
            set
            {
            }
        }

        public int Item { get; set; } //this is not valid
    }
}

For two indexers there are four methods created:

Int32 get_Item(String val)
Void set_Item(String val, Int32 value)
String get_Item(Int32 val)
Void set_Item(Int32 val, String value)

I'd expect my property to create

Int32 get_Item()
Void set_Item(Int32 value)

These overloads are generally acceptable, but somehow the compiler won't let me create such a property.

Please note that I don't need a way to rename the indexer etc, this is known - I need an explanation. This answer: https://stackoverflow.com/a/5110449/882200 doesn't explain why I can have multiple indexers.

like image 783
Piotr Zierhoffer Avatar asked Oct 03 '22 18:10

Piotr Zierhoffer


1 Answers

For the same reason that the following won't compile:

public class Test
{
    public int Foo
    {
        get;
        set;
    }

    public void Foo()
    {
        return;
    }
}

The above results in "The type 'Test' already contains a definition for 'Foo'". Although these could be implemented as a Foo() method and a get_Foo() method, the naming is an implementation detail - at the language level, it's .Foo() and .Foo and since not all languages would support that, the compiler considers it an error.

Similarly, other languages may not support having an indexer and a property with the same name. So, although as you point out this could be compiled as get_Item() and get_Item(Int32), the CLR designers nevertheless chose not to allow it. Although the CLR could have been designed to allow this, it may not be supported at the language level, so they chose to avoid any such issues.

like image 111
Chris Avatar answered Oct 07 '22 19:10

Chris