【问题标题】:C# Parameterized Property class implemented via Generics?通过泛型实现的 C# 参数化属性类?
【发布时间】:2010-06-20 14:18:48
【问题描述】:

我想构建一个通用类,我可以用它在 C# 中实现参数化属性。我想要的基本代码是这样的:

public class ParameterizedProperty<typeReturn, typeIndexer> {
    private typeReturn oReturn = default(typeReturn);

    public typeReturn this[typeIndexer oIndexer] {
        get { return oReturn[oIndexer]; }
        set { oReturn[oIndexer] = value; }
    }
}

但由于 typeReturn 未知/不受限制,编译器正在绘制 oReturn[oIndexer] 行。

那么我该如何让它工作呢?我的第一个(嗯,第二个)想法是使用反射来有条件地找到索引器(如果找不到,则会引发错误),或者可能在类定义上使用 where typeReturn: I??? 修饰符。但是如果我使用修饰符,I??? 会是什么?

感谢您对此问题的任何解决方案!

注意:如何通过反射正确找到索引器(据推测)可在此处找到:http://www.dotnet247.com/247reference/msgs/3/16665.aspx(请参阅最后一条消息)。

编辑: 正如马修在下面指出的那样...我在原始描述中有一些错字/错误...我自己的错,真的...最初是在之前写的床!我想要的代码看起来更像这样:

public class ParameterizedProperty<typeReturn, typeIndexer> {
    private typeReturn[] oReturn;

    public ParameterizedProperty(typeReturn[] oSource) {
        oReturn = oSource;
    }

    public typeReturn this[typeIndexer oIndexer] {
        get { return oReturn[oIndexer]; }
        set { oReturn[oIndexer] = value; }
    }
}

...你敢打赌那行得通吗!?

呃,不完全是!仍在抱怨typeIndexer(想要一个“int-able”类型),但更好!我还添加了一个构造函数来解决讨厌的“我实际上不能将 oReturn 设置为任何东西”的问题 =)

但即使这样看起来也不太正确(数组总是由 INT 索引,对吗?如果是这样就不需要 typeIndexer)...我明天必须在 wurk 再看一遍 =)

【问题讨论】:

  • 你知道对象的索引器会返回一个相同类型的实例吗?这是否意味着成为一棵树/图?
  • 不确定我是否关注 Matthew... 如果基础 oReturn 是 bool[],则返回...啊...现在看 =) T'是一个错字/错误...在 3...2...中编辑原始问题...

标签: c# generics reflection indexer


【解决方案1】:

你想要一些类似的东西:

public class ParameterizedProperty<typeReturn, typeIndexer> {
    private Dictionary<typeIndexer, typeReturn> oReturn = new Dictionary<typeIndexer, typeReturn>();

    public typeReturn this[typeIndexer oIndexer] {
        get { return oReturn[oIndexer]; }
        set { oReturn[oIndexer] = value; }
    }
}

【讨论】:

  • 这确实可以满足我的目的,但是使用 Dictionary 来完成 string[] 或 bool[] 会做的事情似乎有点重量级(别介意那个讨厌的索引器问题;)我猜想字典方法会得到我的投票......但至少几天我会坚持/实验=)
【解决方案2】:

由于您显然不关心将特定业务逻辑附加到此索引属性的 getter 或 setter(就像您可以使用 C# 中的默认索引器或 VB.NET 中的任何属性一样),您需要一个内部存储机制为了做到这一点。

public class ParameterizedProperty<TReturn, TIndexer>
{
    private Dictionary<TIndexer, TReturn> storage = new Dictionary<TIndexer, TReturn>();

    public TReturn this[TIndexer index]
    {
        get
        {
            TReturn output;

            storage.TryGetValue(index, out output);

            return output;
        }
        set { storage[index] = value; }
    }
}

但这实际上只是为您提供了一个类似于 Dictionary 的构造,但不会在索引不存在时引发异常。

【讨论】:

  • 我喜欢 TryGetValue 的使用(我需要查一下,但我猜如果获取失败,“default(TReturn)”会放在输出中?)。是的...不需要将add'l功能附加到这些索引器/属性(我想总是可以重载/实现一个钩子),我只想要... public string[] IDs { get { return ga_sIDs; } } ...没有将 ga_sID 暴露给调用者(也不是它的所有属性/方法)。
  • @CampbeIn: 是的,default(TReturn) 是在检索失败时放入 out 变量的内容。
  • @CampbeIn:此外,如果您需要任意索引方案,Dictionary 是获得所需内容的唯一方法。数组不起作用。 Dictionary 并不是一个特别重量级的对象。
猜你喜欢
  • 2023-03-18
  • 2019-07-27
  • 1970-01-01
  • 2014-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
相关资源
最近更新 更多