我想我以前见过某个地方,但现在我记不起它了,有没有办法用参数制作一个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
答案 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}}
再说一次,我不确定走这条路是否是个好主意。