我知道这是一篇旧文章,但我今天想用 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 作为主要类型,即:myClass1.PrimaryType[0] = primaryType;
再一次,我不确定走这条路是否是个好主意。