要清楚,我想要一个指向指针的行为,这个问题的目的是生成干净,可读的代码。
我有一些代码包含检查多个Dictionary.TryGetValue
调用结果的条件。如果它可以通过一次调用检索所有必需的对象会更清晰,所以我想编写一个扩展,允许我执行以下操作:
Dictionary<string, string> myDictionary; // Initialized somewhere
string x, y, z;
bool foundAllEntries = myDictionary.TryGetValues({"xvalue", out x}, {"yvalue", out y},
{"zvalue", out z});
if (foundAllEntries)
; // Do something with x, y, and z
但是,我无法找到一种方法将扩展方法引用传递给将保存输出的对象。这似乎应该是非常基本的东西。
如何在对象中存储对本地引用的引用?
请注意,这个问题不是要求实现TryGetValues函数的替代方法。我有很多方法可以使这个'工作',但是没有一个方法可以生成像我那样干净的代码。我试图采取。
答案 0 :(得分:9)
这似乎应该是非常基本的东西。
不仅不是基本的,它是完全不可能的:没有办法用ref
或out
来装饰数据类型 - 这些修饰符仅适用于形式方法参数。换句话说,没有“参考变量”或“输出变量”这样的东西;语言中只有“参考参数”和“输出参数”。
此外,您不能将输出或引用参数作为可变长度参数列表(即params
部分)的一部分传递,因此该方法也不起作用。
我可以通过多种方式实现“工作”,但没有一种方法可以像我正在尝试的那样生成干净的代码。
奇怪的是,上述内容并不意味着您无法实现您尝试实施的方案,如果您应用Proxy Design Pattern,则代码几乎与原始代码一样干净。诀窍是链式方法调用,并为结果提供隐式转换运算符,如下所示:
class MyMap {
internal IDictionary<string,string> dict = ...
public ItemGetterResult TryGetValues {
get {
return new ItemGetterResult(this, true);
}
}
}
class ItemGetterResult {
private readonly MyMap map;
private bool IsSuccessful {get;set;}
internal ItemGetterResult(MyMap theMap, bool successFlag) {
map = theMap;
IsSuccessful = successFlag;
}
public static implicit operator bool(ItemGetterResult r) {
return r.IsSuccessful;
}
public ItemGetterResult Get(string key, out string val) {
return new ItemGetterResult(
map
, this.IsSuccessful && map.dict.TryGetValue(key, out val)
);
}
}
现在呼叫如下:
bool foundAllEntries = myDictionary.TryGetValues
.Get("xvalue", out x)
.Get("yvalue", out y)
.Get("zvalue", out z);
答案 1 :(得分:0)
您可以创建一个可变的Reference
类型:
public class Reference<T>
{
public T Value;
}
/* declaration */
bool TryGetValues(
this Dictionary<K,V> dict,
params Tuple<K, Reference<V>>[] requests)
/* call site */
var x = new Reference<string>();
var y = new Reference<string>();
var z = new Reference<string>();
bool foundAllEntries = myDictionary.TryGetValues(
Tuple.Create("xvalue", x),
Tuple.Create("yvalue", y),
Tuple.Create("zvalue", z));