The indexer overload is a special property which accepts arguments. In VB.NET, due to the way VB handles collections, the property is given the name Item(...)
. If you look at the interface for IList<T>
you'll notice it's called Item
there too.
As a result, it has to follow the same rules as properties and method overloading. The return type of a method is not considered part of its calling signature, so overload resolution (how the compiler decides which version of a method to call) cannot distinguish a difference between your indexer implementations.
The intent of an indexer is to provide access to the values stored in a collection-like object. If you can get and set the value associated with a given key or index, the expectation is that you should get back the same value you set.
Your examples are trying to achieve a kind of type duality that isn't isn't the intent of an indexer and isn't achievable in the .NET type system. A type cannot simultaneously be an Action
and a string
. It works against fundamental object-oriented principals to try and make something be two things.
If you want to associate an action and a string, you should create a type that does just that:
public class NamedAction
{
private readonly Action _action;
public string Name { get; }
public NamedAction(Action action, string name)
{
_action = action;
Name = name;
}
public void Invoke()
{
_action.Invoke();
}
}
Now you can have an indexer that gets and sets NamedAction
instances and everything makes a lot more sense.