I have a very large object with many nullable-type variables. I also have a dictionary which I want to fill up with this object's non-null variables.
The code will look something like this
if (myObject.whatever != null)
{
myDictionary.Add("...",myObject.whatever);
}
if (myObject.somethingElse != null)
{
myDictionary.Add("...",myObject.somethingElse);
...
EDIT (Sorry messed up the code)
When we repeat this for the umpteenth time we get a mess of very long code. Is there some shorter way I could write this mess? I know about the Conditional Operator (aka ?) but that's just for assignments. Is there something like that for adding to a collection?
How about an extension method for your dictionary?
public static void AddIfNotNull<T,U>(this Dictionary<T,U> dic, T key, U value)
where U : class {
if (value != null) { dic.Add(key, value); }
}
You could then do this:
myDictionary.AddIfNotNull("...",myObject.whatever);
I'd recommend writing an extension method:
public static class MyExtensions
{
public static void AddIfNotNull<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
if ((object)value != null)
dictionary.Add(key, value);
}
}
Using (object)value != null ensures that this works as you'd expect with nullable types, (e.g. int?) value types, (e.g. int) and reference types (e.g. SomeClass). If you compare it to default(TValue), then an int of 0 will not be added, even though it's not null. If you include a TValue : class requirement, you can't use Nullable<T> as the type, which it sounds like is your most common usage.
You can make a method that hides your if:
AddIfNotNull(myDictionary, "...", myObject.whatever);
private static void AddIfNotNull<K,T>(
IDictionary<K,T> myDictionary
, K key
, T value) {
if (value != default(T)) {
myDictionary.Add(key, value);
}
}
You can earn some "points for style" by making the method an extension (you need to add it to a static class then):
private static void AddIfNotNull<K,T>(
this IDictionary<K,T> myDictionary
, K key
, T value) {
if (value != default(T)) {
myDictionary.Add(key, value);
}
}
myDictionary.AddIfNotNull(myDictionary, "...", myObject.whatever);
If you know that you are inserting only reference type objects, replace default(T) with null and add a class T constraint to the generic.
public void addToDict(string ?myObj, Dictionary<,> myDict) {
if (myObj != null)
myDict.Add("...", myObj);
}
addToDict(myObject.whatever, myDict);
addToDict(myObject.somethignElse, myDict);
etc
Related
Is there any way how to write TryGetValue on one line in If condition. Normal way of calling TryGetValue would be:
string value;
Dictionary.TryGetValue("Key", out value);
If(value == "condition") { ... }
What I am looking for would be something like this.
If(Dictionary.TryGetValue("Key", out string) == "Condition") { ... }
I know that line wouldn't work, however it shows what is desired result.
Is there any way how to achieve this?
You need to use the returned bool first but then you can use the out parameter(with >= C# 7):
if (Dictionary.TryGetValue("Key", out string value) && value == "Condition")
{
//...
}
MSDN:
Starting with C# 7.0, you can declare the out variable in the argument
list of the method call, rather than in a separate variable
declaration.
If you're not using C#7 or you want it even shorter you could use this extension:
public static bool TryEvaluateValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, Func<TValue, bool> evalValue)
{
TValue val;
if(!dict.TryGetValue(key, out val))
return false;
return evalValue(val);
}
Then your if-condition becomes:
if (Dictionary.TryEvaluateValue("Key", value => value == "Condition"))
{
//...
}
I have two classes with no inheritance relationship (well, excepting being Object):
class A
{
Member1 m1;
Member2 m2;
}
class B
{
Member1 m3;
Member2 m4;
}
Each member of a class is paierd with a member of the same arbitrary type in the other class, it might or might not have the same name, it can be null.
I would like to do something like this:
if (b.m3 != null) a.m1 = b.m3;
just to update values that are not null, where a is an instance of class A and b is an instance of class B.
The number of members to update might grow with time, I'd like some more general and elegant way to do the update, something to be used like this:
a.Update(d => d.m1, b.m3)
I have tried with an extension method:
public static void Update<TSource, TKey>(this TSource source, Func<TSource, TKey> key, TKey newValue)
where TSource : A
{
if (newValue != null)
{
key(source) = newValue;
}
}
but there is clearly something wrong because I get an exception saying that the left-hand side of the the equality key(source) must be a variable.
Any ideas?
The reason this doesn't work is because a Func is literally a function that returns a value. When called you have to assign that value to a variable, thus the error message you are getting. Instead of a Func you could use an Action and pass both the source and the key to it.
public static void Update<TSource, TKey>(
this TSource source,
Action<TSource, TKey> action,
TKey newValue)
where TSource : A
{
if (newValue != null)
{
action(source, newValue);
}
}
Then call it like this.
a.Update((myA, val) => myA.m1 = val, b.m3);
But really it would be simpler to just do the following
a.m1 = b.m3 ?? a.m1;
That will assign b.m3 to a.m1 if it is not null. Otherwise it just assigns a.m1 to itself.
Although for this specific case you should look into mapping libraries that can handle this type of thing for you.
You could do something like this
Member1 m1;
public Setm1(Member1 in)
{
if (in != null) m1 = in;
}
Then your code is very simple:
a.Setm1(b.m3);
Or you could use the accessor (with the same code) and you would have
public Member1 Setm1
{
set { if (value != null) m1 = value;
}
a.Setm1 = b.m3;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get null instead of the KeyNotFoundException accessing Dictionary value by key?
I currently have lots of Dictionary<string, T> uses in my project, and most of them look like so:
if (myDic.ContainsKey("some key"))
localVar = myDic["some key"];
It's not very effecient too, as it does two calls to the dictionary, which can be resource consuming. TryGetValue() is a cool thing, but it just doesn't do it in one line.
I just want to get null if there is no such key from var v = myDic[key]. How do I do that?
You may use an extension method with TryGetValue:
public static U GetValueByKeyOrNull<T, U>(this Dictionary<T, U> dict, T key)
where U : class
{
U value;
dict.TryGetValue(key, out value);
return value;
}
thanks to which you'll be able to write
somedict.GetValueByKeyOrNull("key1")
In the end trying to do this very thing I came up with a variant using a deriving from dictionary class with explicit interface implementation: How to get null instead of the KeyNotFoundException accessing Dictionary value by key?
That is
public interface INullValueDictionary<T, U>
where U : class
{
U this[T key] { get; }
}
public class NullValueDictionary<T, U> : Dictionary<T, U>, INullValueDictionary<T, U>
where U : class
{
U INullValueDictionary<T, U>.this[T key]
{
get
{
U val;
dict.TryGet(key, out val);
return val;
}
}
}
and use it instead of the original dictionary everywhere:
//create some dictionary
NullValueDictionary<int, string> dict = new NullValueDictionary<int, string>
{
{1,"one"}
};
//have a reference to the interface
INullValueDictionary<int, string> idict = dict;
string val = idict[2]; // null
val = idict[1]; // "one"
I don't like to deal with null so my implementation will look like this:
interface Maybe<T> {
bool HasValue {get;}
T Value {get;}
}
class Nothing<T> : Maybe<T> {
public bool HasValue { get { return false; } }
public T Value { get { throw new Exception(); } }
public static const Nothing<T> Instance = new Nothing<T>();
}
class Just<T> : Maybe<T> {
private T _value;
public bool HasValue { get { return true; } }
public T Value { get { return _value; } }
public Just(T val) {
_value = val;
}
}
Maybe is a object that can contain value or not. Note that Nothing class contains static field Instance. We can use this value instead of creating new value each time we need to return Nothing from function.
Now, we need to create our own dictionary class:
class MyDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> _dict;
...
public Maybe<TValue> this[TKey key] {
TValue val;
if (_dict.TryGetValue(key, out val)) {
return new Just<TValue>(val);
return Nothing<TValue>.Instance;
}
}
Advantage of this approach is not clear, because C# doesn't have pattern matching. But it can be emulated with dynamic:
void ProcessResult(Just<string> val) {
Console.WriteLine(val);
}
void ProcessResult(Nothing<string> n) {
Console.WriteLine("Key not found");
}
var dict = new MyDictionary<string, string>();
...
dynamic x = dict["key"];
ProcessResult(x);
I think that this is very clear way to express the fact that dictionary can't always return meaningful result. Also it is obvious for reader that function overload ProcessResult(Just<T>) will be called only for values that present in dictionary and other overload will be called in case when key is not found.
Pros:
Type serves as a specification.
Dictionary can contain both value and reference types.
Cons:
More keystrokes.
Little more complexity to deal with.
I decided to do it like this:
class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new TValue this[TKey key]
{
get
{
TValue value;
return TryGetValue(key, out value) ? value : default(TValue);
}
set { base[key] = value; }
}
}
It lets me use it like any other dictionary, through square brackets. Since I'm not going to use this with value types as TValue, I think it's good enough a solution.
I'd like to test if an id was not yet known or, if it is known, if the associated value has changed. I'm currently using code similar to this, but it is hard to understand for those not familiar with the pattern. Can you think of a way to make it more readable while keeping it short in LOC?
string id;
string actual;
string stored;
if (!someDictionary.TryGetValue (id, out stored) || stored != actual) {
// id not known yet or associated value changed.
}
You can write an extension method with a good name:
public static class Utility
{
public static bool ValueChangedOrUnknown(this Dictionary<string, string> dictionary, string id, string actual)
{
string stored = null;
return (!dictionary.TryGetValue(id, out actual) || stored != actual);
}
}
so later you can use
string id;
string actual;
if (someDictionary.ValueChangedOrUnknown(id, actual) {
// id not known yet or associated value changed.
}
So I would most probably break it up and give it meaningful names. This is more to read, but you don't need much to say in comments:
bool isKnown = someDictionary.TryGetValue (id, out stored);
// can only change when it is known
bool valueChanged = isKnown && stored != actual;
// quite self-explanatory, isn't it?
if (!isKnown || valueChanged)
{
}
wrap each part of the || into its own method or property, than you can write it like this
if ( IdIsNew() || IdChanged())
Duality.
if (!(someDictionary.TryGetValue (id, out stored) && stored == actual)) ...
Not sure if it is more readable though... but it's good to know.
It looks fine to me...reads as easy as any other 2 condition if statement. About the only thing I'd possibly change is to flip the negations for an early exit:
if (someDictionary.TryGetValue(id, out stored) && stored == actual) {
return;
}
// store new value
I don't see any confusion in it at all, have never thought of it as a particularly troublesome idiom, and humbly suggest that those C# devs confused by it get used to it. It's common, succint, and gives as many LOC to the problem as it deserves. Turning it into 10 lines of code makes it way too important.
If I used it often, an extension method named something like ContainsEqualValue would be appropriate - but I'd use the exact same code in the extension method as you have.
I'd prefer a new method:
public bool ShouldSetValue(Dictionary someDictionary, object id,object actualValue)
{
string stored;
if (someDictionary.TryGetValue (id, out stored))
{
if (stored != actualValue)
return true;
}
else
{
return true;
}
}
then in the existing method I'd just:
if (ShouldSetValue(someDictionary,id,actual))
{
someDictionary[id]=actual;
}
An extension method would be slick:
public static class DictionaryExtensions
{
public static bool ShouldAddValue<TKey, TValue>(this Dictionary<TKey, TValue> someDictionary, TKey id, TValue actual)
{
TValue stored;
return (!someDictionary.TryGetValue(id, out stored) || !stored.Equals(actual));
}
}
Usage:
someDictionary.ShouldAddValue("foo", "bar")
If you mean that you have to do this repeatedly, and it is long and ugly, abstract the logic to another class and use an extension method.
public static class DictionaryExtensions
{
public static DictionaryChecker<TKey,TValue> contains<TKey,TValue>(this IDictionary<TKey,TValue> dictionary, TValue value)
{
return new DictionaryChecker<TKey,TValue>(value, dictionary);
}
}
public class DictionaryChecker<TKey,TValue>
{
TValue value;
IDictionary<TKey,TValue> dictionary;
internal DictionaryChecker(TValue value, IDictionary<TKey, TValue> dictionary)
{
this.value = value;
this.dictionary = dictionary;
}
public bool For(TKey key)
{
TValue result;
return dictionary.TryGetValue(key, out result) && result.Equals(value);
}
}
Now replace your code with:
if(!someDictionary.contains(actual).For(id)){
// id not known yet or associated value changed.
}
public T GetValue(int id, object actual)
{
object stored;
if (someDictionary.TryGetValue (id, out stored) || stored == actual)
return stored;
return new object();
}
While I recognize that the "try" pattern is necessary, I dislike implementations which require an "out" parameter. It would seem much more useful have functions similar to TryGetValue:
TryGetDictValue(dictionary, key) returns null if key is not in dictionary
TryGetDictValue(dictionary, key, defaultValue) returns defaultValue if key is not in dictionary
TryGetDictValue(dictionary, key, valueReturningDelegate) invokes the supplied delegate if key is not in dictionary and returns its result
In every case, the return type of the result would be that of the dictionary's data.
It's too bad there's no way to sneak into a time machine and make such things be methods of Dictionary. On the other hand, one could implement them as static functions taking a dictionary as the first parameter.
Basically, I want something like this:
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.Add(null, "Nothing");
dict.Add(1, "One");
Are there any built into the base class library that allow this? The preceding code will throw an exception at runtime when adding the null key.
You could avoid using null and create a special singleton value class that does the same thing. For example:
public sealed class Nothing
{
public static readonly Nothing Value = new Nothing();
private Nothing() {}
}
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.add(Nothing.Value, "Nothing");
dict.add(1, "One");
This approach will fail to work if you intend to make your collection more strongly typed - let's say for example you want the key to be a string. Since string is sealed you can't inherit from it to create a "special value" substitute for null. Your alternatives become a bit more complicated. You could:
Create some special constant value to represent the "empty" / "null" case. Kind of hacky and definitely a path to confusion. This can be a viable approach if the dictionary is completely private to some implementation class and you can write some Encode/Decode utility methods to avoid spreading the knowledge of how you translate keys all over the place.
Create your own implementation of IDictionary that internally delegates to a Dictionary<> instance - except for the case of null. This violates the documented expectations for the IDictionary<> interface which does say that null keys should throw an exception. But you may be able to get away with it if it's the only way to solve your real problem. This only works if you own and create the dictionary instance.
Find a way to solve your problem without storing a "null" key in the dictionary. For example, consider not populating the null key in the dictionary and having some special case logic to deal with it. Keys have to be hashable and comparable to work with the underlying implementation, which is why null is prohibited normally.
As an aside, does your dictionary key really need the key to be object? This can lead to subtle bugs due to reference equality being used where you may have intended Equals() to be evaluated as the basis for comparison.
How about this?
public class NullableDictionnary<T1, T2> : Dictionary<T1, T2>
{
T2 null_value;
public T2 this[T1 key]
{
get
{
if (key == null)
{ return null_value; }
return base[key];
}
set
{
if (key == null)
{ null_value = value; }
else
{ base[key] = value; }
}
}
}
NameValueCollection can take a null key but it does not implement IDictionary. It would however be pretty easy to derive from DictionaryBase and provide Add/Remove/Indexers etc that simply replace null with something built in like:
class MyDictionary : DictionaryBase {
private readonly object nullKey = new object();
void Add(object key, string value) {
if ( key == null ) { key = nullKey; }
.. call base methods
}
}
You can simply use ValueTuple as a wrapper for key, for example:
Dictionary<ValueTuple<string?>, string>
No need for a different implementation of Dictionary.
Take a look at my answer here:
https://stackoverflow.com/a/22261282/212272
You will also be able to keep your dictionary strongly typed:
var dict = new Dictionary<NullObject<int?>, string>();
dict[1] = "one int";
dict[null] = "null int";
Assert.AreEqual("one int", dict[1]);
Assert.AreEqual("null int", dict[null]);
If key is enum, you can use not existing value instead of null like (YourEnum)(-1)
Does the key literally need to be NULL? The key in the collection works out to be an index. It doesn't make a lot of sense to me to have NULL for an index in a collection.
Maybe create a new class
public class ObjectEntry
{
public object objRef;
public string desc;
public ObjectEntry(object objectReference)
{
objRef = objectReference;
if (objRef = null) {desc = "Nothing";}
else {desc = objRef.Description;} //or whatever info you can get from a proper objRef value
}
}
newObj = new ObjectEntry(null);
dict.add(newObj, newObj.desc);
A slight variation on jestro's answer to make for a cleaner(to me) solution that makes it more explicit what you are trying to do. Obviously this could be extended as needed. But you get the picture, just make a wrapper.
public class NullDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
private TValue _default;
public new TValue this[TKey key]
{
get {
if(key == null)
{
return _default;
}
return _decorated[key];
}
}
private Dictionary<TKey, TValue> _decorated;
public NullDictionary( Dictionary<TKey,TValue> decorate, TValue defaultValue = default)
{
_decorated = decorate;
_default = defaultValue;
}
}