2

Consider a situation: I have a method which use DataRow:

public void MyMethod (DataRow input)
{
    DoSomething(input["Name1"]);
}

But now I have some another input types with indexer which I want to pass to this method. St like:

public void MyMethod (AnyTypeWithIndexer input)
{
    DoSomething(input["Name1"]);
}

But I haven't found anything like that. I tried IDictionary but it didn't work. Is there any super type st like "Indexable" or anything with which I can replace the "AnyTypeWithIndexer"?

Note: I still need this method to pass the DataRow and also my custom class (which I want to implement).

Can anybody help?

Thanks.

xMichal
  • 624
  • 2
  • 7
  • 19
  • You havent asked a question. What is it you are trying to accomplish? Are you asking what type `AnyTypeWithIndexer` should be? Are you asking what type `DoSomething` should take as a parameter? Its extremely unclear – maccettura Apr 30 '20 at 15:16
  • Edited. Better now? – xMichal Apr 30 '20 at 15:21
  • 1
    There's no 'interface' behind [indexers](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/using-indexers) - you _could_ [use reflection](https://stackoverflow.com/questions/1347936/identifying-a-custom-indexer-using-reflection-in-c-sharp) though. – stuartd Apr 30 '20 at 15:22
  • Reflection is an option, but at this point I think just making method overloads would be better. – maccettura Apr 30 '20 at 15:23

2 Answers2

5

No, unfortunately, there is no interface that automatically applies to "all classes with an indexer that takes a string argument and returns an object".

What you can do, however, is to create a "proxy class" that implements such an interface yourself:

public interface IStringToObjectIndexable
{
    object this[string index] { get; set; }
}

class DataRowWrapper : IStringToObjectIndexable
{
    private readonly DataRow row;

    public DataRowWrapper(DataRow row) => this.row = row;

    public object this[string index]
    {
        get => row[index];
        set => row[index] = value;
    }
}

MyMethod can now be declared as follows:

public void MyMethod(IStringToObjectIndexable input)
{
    DoSomething(input["Name1"]);
}

// Compatibility overload
public void MyMethod(DataRow input) => MyMethod(new DataRowWrapper(input));
Heinzi
  • 167,459
  • 57
  • 363
  • 519
1

You can use dynamic type, but you will need to be noticed about the disadvantages of dynamic, such as performance drawbacks because of DLR, and the fact that type safety should be on your shoulders

    public class WithIndexer
    {
        public int this[string key] => 42;
    }

    public static async Task Main()
    {
        Dictionary<string, int> a = new Dictionary<string, int>();
        a.Add("meow", 41);

        Foo(a, "meow");
        Foo(new WithIndexer(), "key");
    }

    private static void Foo(dynamic indexed, string key)
    {
        Console.WriteLine(indexed[key]);
    }

Output:

41
42