C# Type as object with 索引器

C# Type as object with indexer

考虑一种情况: 我有一个使用 DataRow 的方法:

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

但现在我有一些其他带有索引器的输入类型,我想将其传递给此方法。喜欢:

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

但我还没有找到类似的东西。我试过 IDictionary 但它没有用。 是否有像 "Indexable" 之类的超类型 st 或任何我可以用来替换 "AnyTypeWithIndexer" 的东西?

注意:我仍然需要此方法来传递 DataRow 以及我的自定义 class(我想实现)。

有人可以帮忙吗?

谢谢。

您可以使用 dynamic 类型,但是您需要注意 dynamic 的缺点,例如由于 DLR 导致的性能缺陷,以及类型安全应该在您的肩膀

    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]);
    }

输出:

41
42

没有,很遗憾,没有自动适用于"all classes with an indexer that takes a string argument and returns an object"的接口。

但是,您可以创建一个 "proxy class" 来实现这样的接口 你自己:

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 现在可以声明如下:

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

// Compatibility overload
public void MyMethod(DataRow input) => MyMethod(new DataRowWrapper(input));