Can I save a link to a local link?
To be clear, I need pointer-to-pointer behavior, and the purpose of this question is to generate clean, readable code.
I have some code that contains conditions that test the result of multiple calls Dictionary.TryGetValue
. It would be cleaner if it could get all the objects it needs with a single call, so I wanted to write an extension that would allow me to do the following:
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
However, I cannot find a way to pass the extension method references to the objects that will contain the output. It looks like it should be very simple.
How do I store a link to a local link in an object?
Please note that this question does not require alternative approaches to implement the TryGetValues ββfunction. There are many ways to make this "work", but none of them generate as clean code as the approach I'm trying to take.
source to share
It looks like it should be very simple.
Not only is this not fundamental, but also impossible: there is no way to decorate the data type with ref
or out
- these modifiers are applicable exclusively to the parameters of formal methods. In other words, there is no such thing as "reference variable" or "output variable"; the language only has "reference parameters" and "output parameters".
Also, you cannot pass output or reference parameters as part of a variable length argument list (i.e. part params
) for the approach to fail.
There are many ways to make this "work", but nobody generates code as clean as the approach I'm trying to do.
Curiously, the above does not mean that you cannot implement the schema you are trying to implement, leaving the code almost as clean as your original if you apply the Proxy Pattern Template . The trick is chaining method calls and providing an implicit conversion operator for the result, for example:
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)
);
}
}
Now the call looks like this:
bool foundAllEntries = myDictionary.TryGetValues
.Get("xvalue", out x)
.Get("yvalue", out y)
.Get("zvalue", out z);
source to share
You can create a mutable type 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));
source to share