【问题标题】:Named indexed property in C#?C# 中的命名索引属性?
【发布时间】:2014-05-29 16:05:58
【问题描述】:

一些语言(例如 Delphi)有一种非常方便的创建索引器的方法:不仅可以为整个类建立索引,甚至可以为单个属性建立索引,例如:

type TMyClass = class(TObject)
protected
    function GetMyProp(index : integer) : string;
    procedure SetMyProp(index : integer; value : string);
public
    property MyProp[index : integer] : string read GetMyProp write SetMyProp;
end;

这很容易使用:

var c : TMyClass;

begin
    c = TMyClass.Create;
    c.MyProp[5] := 'Ala ma kota';
    c.Free;
end;

有没有办法在 C# 中轻松实现相同的效果?

【问题讨论】:

  • @nawfal 我在解决方案中看不到接口? (这是知识共享问题,顺便说一句 - 答案也是我的)
  • q 完全一样,OP 是在命名索引器之后。您可以在该线程中提供答案。你在回答的时候可能没有看到原始的q,但是如果你有,那么添加另一个问题来仅仅回答是不合适的。顺便说一句,好的答案,+1(在一些相关的问题中,这个答案也包括在内)。
  • @nawfal 我相信,当您提出一个名为“回答您的问题 - 以问答方式分享知识”的问题时,会有一个特殊的复选框。
  • 是的,但这是为非重复问题保留的。我的问题不在于您的答案(“知识”),而在于问题。没什么大不了。重复总是发生。由我们作为负责任的成员进行清理。尽我的本分。

标签: c# indexed-properties


【解决方案1】:

众所周知的解决方案是创建一个代理类:

public class MyClass
{
    public class MyPropProxy
    {
        private MyClass c;

        // ctor etc.

        public string this[int index]
        {
            get
            {
                return c.list[index];
            }
            set
            {
                c.list[index] = value;
            }
        }
    }

    private List<string> list;
    private MyPropProxy myPropProxy;

    // ctor etc.

    public MyPropProxy MyProp
    { 
        get
        {
            return myPropProxy;
        }
    }
}

但是(除此之外,这实际上解决了问题),这个解决方案主要引入了缺点:

  • 它会导致代码被(可能)很多小的代理类污染。
  • 提出的解决方案打破了封装一点(内部类访问外部类的私有成员),更好的解决方案是将列表实例传递给MyPropProxy 的ctor,这需要更多代码。
  • 我不建议公开内部帮助程序类。人们可以通过引入额外的接口来解决这个问题,但这甚至是一个需要实现的实体(测试、维护等)

不过,还有另一种方法。它还对代码造成了一点污染,但肯定比前一个少很多:

public interface IMyProp
{
    string this[int index] { get; }
}

public class MyClass : IMyProp
{
    private List<string> list;

    string IMyProp.this[int index]
    {
        get
        {
            return list[index];
        }
        set
        {
            list[index] = value;
        }
    }

    // ctor etc.

    public IMyProp MyProp 
    {
        get
        {
            return this;
        }
    }
}

优点:

  • 没有代理类(占用内存空间,仅用于单一目的并且(在最简单的解决方案中)破坏封装。
  • 简单的解决方案,只需很少的代码即可添加另一个索引属性

缺点:

  • 每个属性都需要不同的公共接口
  • 随着索引属性的增加,类实现的接口越来越多

这是将索引属性引入 C# 的最简单(就代码长度和复杂性而言)的方法。当然,除非有人发布更短更简单的帖子。

【讨论】:

  • 显式实现的接口,没想到,不错!
  • 这很干净.. 但可以通过使用模板使其更干净:public interface IIndexedProp&lt;IndexT, ValueT&gt; { ValueT this[IndexT index] { get; } } 用法:public class MyClass: IIndexedProp&lt;int, string&gt; 其余部分相同。这样,您只需要 1 个接口 - 可能更多用于仅获取/设置道具。
猜你喜欢
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多