带参数的Getter属性

时间:2011-05-22 14:46:40

标签: c# properties

我想我以前见过某个地方,但现在我记不起它了,有没有办法用参数制作一个getter属性?

我的意思是,因为我可以转换“float getSize();” “浮动大小”

float getSize() {
    return this.size;
}

float Size {
    get { return this.size; }
}

然后,我可以转换为例如“float getSize(String unit);” “浮动大小(字符串单位)”或类似的东西?

float getSize(String unit) {
    return this.size;
}

float Size(String unit) {
    get {
        if (unit == Unit.Meters)
            return this.size/100;
        else
            return this.size;
    }
}

我认为根本没有使用功能的问题,但这样看起来可能更好:P

4 个答案:

答案 0 :(得分:31)

回答这个问题:不,这是不可能的,正如已经指出的那样,带参数的getter看起来就像一个方法。

您正在考虑的事情可能是索引的默认属性,如下所示:

class Test
{
    public string this[int index] 
    {
        get { return index.ToString(); } 
    }
}

这允许您索引到Test的实例,如下所示:

Test t = new Test();
string value = t[1];

答案 1 :(得分:19)

但好奇心...... 在VB .Net

中可以使用带参数的属性

如下所示:

  Public ReadOnly Property oPair(param As String) As Result
    Get
       'some code depends on param
    End Get
  End Property

它不如常规功能更好,但有时候有这种可能性很好。

答案 2 :(得分:0)

类对象可以通过使属性返回struct来合理有效地获得表现为命名索引属性getter的东西,该OrderedCollection<T>只保存对类对象的私有引用并包含索引属性getter链接到类中的方法。这样的单项结构可以基本上免费生成(它可能适合寄存器,并且将加载另一个寄存器中的值; JIT甚至可以识别相同的寄存器可以用于这两个目的),所以如果使用这样的getter使得代码更具可读性,那么这是一个有利于它的实质性论据。

不幸的是,结构成员无法指示它们是否修改了底层结构,因此无法对索引属性设置器使用相同的方法。虽然它会有所帮助,但它可以有一个struct ByIndexAccessor { OrderedCollection<T> owner; ByIndexAccessor(OrderedCollection<T> o) { owner = o; } T this[int index] { get { return owner.handleGet(index); } set { owner.handleSet(index, value); } } } ByIndexAccessor ByIndex { get {return new ByIndexAccessor(this); } } ,例如:

myCollection.ByIndex[3] = newThing;

并且说set,C#会拒绝这样的代码,因为它无法知道这个特定的索引{{1}}实现可以安全地用在只读结构上。

答案 3 :(得分:0)

我知道这是一篇旧帖子,但我今天想用 C# 来做这件事。这是否是一件好事可能落在了“不是”的一边。然而,我在 (https://social.msdn.microsoft.com/forums/en-US/5a25bc83-990e-4657-aa9c-69bca5158d48/overloaded-c-properties-with-arguments?prof=required) 上看到了 Mark Jones 发表的一个有趣的想法,但我不太喜欢它的感觉。

所以我根据他写了我自己的(我在 .Net 5.0 中使用 Nullable = enable):

class ParameterizedProperty<T>
{
    private readonly Func<int, T> getter;
    private readonly Action<int, T> setter;

    public T this[int index]
    {
        get => this.getter(index);
        set => this.setter(index, value);
    }

    public ParameterizedProperty(Func<int, T> getter, Action<int, T> setter)
    {
        this.getter = getter;
        this.setter = setter;
    }
}

class NamedParameterizedProperty<T>
{
    private readonly Func<int, T> indexedGetter;
    private readonly Action<int, T> indexedSetter;
    private readonly Func<string, T> namedGetter;
    private readonly Action<string, T> namedSetter;

    public T this[int index]
    {
        get => this.indexedGetter(index);
        set => this.indexedSetter(index, value);
    }

    public T this[string name]
    {
        get => this.namedGetter(name);
        set => this.namedSetter(name, value);
    }

    public NamedParameterizedProperty(Func<int, T> indexedGetter, Action<int, T> indexedSetter, Func<string, T> namedGetter, Action<string, T> namedSetter)
    {
        this.indexedGetter = indexedGetter;
        this.indexedSetter = indexedSetter;
        this.namedGetter = namedGetter;
        this.namedSetter = namedSetter;
    }
}

class ReadOnlyParameterizedProperty<T>
{
    private readonly Func<int, T> getter;

    public T this[int index] => this.getter(index);

    public ReadOnlyParameterizedProperty(Func<int, T> getter)
    {
        this.getter = getter;
    }
}

class ReadOnlyNamedParameterizedProperty<T>
{
    private readonly Func<int, T> indexedGetter;
    private readonly Func<string, T> namedGetter;

    public T this[int index] => this.indexedGetter(index);
    public T this[string name] => this.namedGetter(name);

    public ReadOnlyNamedParameterizedProperty(Func<int, T> indexedGetter, Func<string, T> namedGetter)
    {
        this.indexedGetter = indexedGetter;
        this.namedGetter = namedGetter;
    }
}

关于我的解决方案的一点:我为 getter/setter 选择了 Func<> 和 Action<>,因为我不希望这个辅助类必须需要它支持的基础属性的任何知识。相反,拥有该属性的类将具有用于 get_X / set_X(或您希望使用的任何命名约定)的公共(或私有)方法来处理所有事情 - 例如验证。

现在说到我的用例:我有一个类,它有一个特定类型的内部数组。我有一个默认的索引器属性 public primaryType this[int index],但它有几个其他类型,它可以理解并且可以为 primaryType 转换为/从。但是,我不能执行 public otherType this[int index],而且我真的不想执行称为“get_OtherType”和“set_OtherType”之类的公共方法。

这些辅助类让我可以做类似的事情:

public ParameterizedProperty<OtherType> OtherType { get; }

public MyClass()
{
    this.OtherType = new(get_OtherType, set_OtherType);
}

private OtherType get_OtherType(int index) 
{
    /* validate index, convert PrimaryType at index to OtherType and return. */
}

private void set_OtherType(int index, OtherType value)
{
    /* validate index, validate value, convert to PrimaryType and set to internal array. */
}

然后在使用这个类的其他类/UI 中,'OtherType' 对他们来说更方便,然后是 'PrimaryType',我可以让他们做像 myClass1.OtherType[0] = otherType; 这样的事情,但是如果他们使用主要类型,那么他们可以做 myClass1[0] = primaryType - 或者如果我只是想保持一致/明确,我没有默认的索引器属性,我也使用 ParameterizedProperty 作为主要类型,IE:{{ 1}}

再说一次,我不确定走这条路是否是个好主意。