I am using a Library with a class that have the following constructors:
public JobDataMap(IDictionary<string, object> map);
public JobDataMap(IDictionary map);
I created an instance of JobDataMap:
var jdm = new JobDataMap(new Dictionary<String, Object> {
{ "Manager", myObject }
});
But I am getting the compilation error:
The call is ambiguous between the following methods or properties:
'JobDataMap.JobDataMap(IDictionary<string, object>)' and 'JobDataMap.JobDataMap(IDictionary)'
How to solve this?
You can enforce the type being passed like so:
var jdm = new JobDataMap((IDictionary<string, object>)new Dictionary<String, Object> {
{ "Manager", myObject }
});
Or you could make a factory method and make the non-generic constructor (I'm assuming you use this less) private:
public class JobDataMap
{
public JobDataMap(IDictionary<string, object> map)
{
}
private JobDataMap(IDictionary map)
{
}
public static JobDataMap FromNonGenericMap(IDictionary map)
{
return new JobDataMap(map);
}
}
Usage:
var jdm = JobDataMap.FromNonGenericMap(someNonGenericDictionary);
and then you can use the regular generic one like so:
var jdm = new JobDataMap(new Dictionary<String, Object> {
{ "Manager", myObject }
});
You can cast it to the type for the constructor you want it to use:
var jdm = new JobDataMap((IDictionary<string, object>) new Dictionary<String, Object> {
{ "Manager", new object() }
});
This design does seem a bit dubious, however...
Related
I have a class, with some global and constant dictionaries. Like:
public static class Constants
{
public static Dictionary<string, MyObject> MyDictionary= new Dictionary<string, MyObject>()
{
{"first", new MyObject()},
{"second", new MyObject()},
};
}
Lets say I would like another dictionary, to be like that only with some added and removed elements. Is there a way to achieve that, within the static class? I imagine something like:
public static Dictionary<string, MyObject> MyOtherDictionary = MyDictionary.Remove("second").Add("Third", new MyObject())
But I know that does not work, so is there any way I can achieve this?
No, that doesnt work in this way for two reasons:
Remove returns a bool, you can't use Add on a bool
even if you make it compile, you don't want to modify the other dictionary but you want to create a new dictionary which contains similar items, you can use the constructor:
public static Dictionary<string, MyObject> MyOtherDictionary;
// ...
static Constants
{
MyOtherDictionary = new Dictionary<string, MyObject>(MyDictionary);
MyOtherDictionary.Remove("second");
MyOtherDictionary.Add("Third", new MyObject());
}
You could do it using properties instead
public static class Constants
{
public static Dictionary<string, MyObject> myDictionary
{
get
{
return new Dictionary<string, MyObject>()
{
{ "first", new MyObject()},
{ "second", new MyObject()},
};
}
}
static Dictionary<string, MyObject> _myOtherDictionary;
public static Dictionary<string, MyObject> myOtherDictionary
{
get
{
_myOtherDictionary = myDictionary;
_myOtherDictionary.Remove("first");
_myOtherDictionary.Add("third", new MyObject());
return _myOtherDictionary;
}
}
}
I have following parent class:
public class BaseType
{
public abstract Dictionary<string, object> dict { get; set; }
}
Child class:
public override Dictionary<string, object> dict
{
get
{
return fn();
}
set
{
//set dictionary[key]=value }
}
fn is implemented in child class as:
public static Dictionary<string, object> fn()
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary.Add("key1", "0");
dictionary.Add("key2", "something");
return dictionary;
}
I need to access this dictionary as follows:
BaseType test=new Child();
test.dict["key1"]=1;//set property
object strGet= test.dict["key2];//get property
How can I achieve the above get and set?
Your parent class is already invalid. You cannot have a property that takes arguments.
You can only expose the dictionary as a property itself. Note that you also need to make the class abstract as well:
public abstract class BaseType
{
public abstract Dictionary<string, object> Dict { get; set; }
}
Then, in subtypes of that class, you can set up the getter and setter so it returns a custom dictionary:
public class MyType : BaseType
{
public override Dictionary<string, object> Dict
{
get
{
return GetSomeDictionary();
}
set
{
DoSomethingWith(value);
}
}
}
Note, that this does not allow you to overwrite the behavior when you do someObj.Dict["key"] = "foo". The item accessor is built into the dictionary type, and you cannot overwrite that from within your class.
What you could do is expose a IDictionary<string, object> instead and provide your own type that wraps a normal dictionary but exposes your desired behavior instead.
If the whole purpose of your code is just to provide some default value for the dictionary, then you can solve this a lot easier:
public class MyType : BaseType
{
private Dictionary<string, object> _dict = null;
public override Dictionary<string, object> Dict
{
get
{
if (_dict == null)
{
_dict = InitializeDictionary();
}
return _dict;
}
set
{
_dict = value;
}
}
}
Where InitializeDictionary() returns a new dictionary with the default values.
I got it!! This way we can dynamically set the value of any key in dictionary.
public object objValue;
public string strKey;
public override Dictionary<string, object> dictionary
{
get
{
return fn();
}
set
{
setTest(strKey,objValue);
}
}
public void setTest(string strKey, object objValue)
{
dictionary[strKey] = objValue;
}
I have defined a class which contains only one member of type dictionary of dictionary. I want to serialize it to JSON format and hence using JavaScriptSerializer.
[Serializable]
class X
{
private readonly Dictionary<string, Dictionary<string, string>> dic;
public X()
{
dic = new Dictionary<string, Dictionary<string, string>>();
}
public void Add()
{
this.dic.Add("x", new Dictionary<string, string>() { { "a", "b" } });
}
}
class Program
{
static void Main(string[] args)
{
var x = new X();
x.Add();
string msg = new JavaScriptSerializer(new SimpleTypeResolver()).Serialize(x);
var y = new JavaScriptSerializer(new SimpleTypeResolver()).Deserialize<X>(msg);
}
}
Now, the above code run successful without any error/exception but the results are not as excepted. The serialized string of class X in the above code is
{"__type":"Testing.X, Testing, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}
Can anybody tell me whats the problem in the above code and what I'm missing? Also, if in the above class, I change the inner dictionary type to Dictionary<string, IEntity> then what all I have to do to serialize it.
JavaScriptSerializer is designed to only pull public properties by default. Once you expose the field through a getter or setter you should be able to serialize this data.
[Serializable]
class X
{
private readonly Dictionary<string, Dictionary<string, string>> dic;
public X()
{
dic = new Dictionary<string, Dictionary<string, string>>();
}
public void Add()
{
this.dic.Add("x", new Dictionary<string, string>() { { "a", "b" } });
}
//Property exposing private field 'dic'.
public Dictionary<string, Dictionary<string, string>> Dictionary
{
get
{
return dic;
}
}
}
class Program
{
static void Main(string[] args)
{
var x = new X();
x.Add();
string msg = new JavaScriptSerializer(new SimpleTypeResolver()).Serialize(x);
var y = new JavaScriptSerializer(new SimpleTypeResolver()).Deserialize<X>(msg);
}
}
In this case, the string contains the following output (look to the very end):
{"__type":"ConsoleApplication1.X, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Dictionary":{"x":{"a":"b"}}}
I have create a Class named "EngDictionary". and Then i define a dictionary in a function
e.g:
public void Dict()
{
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("Classifieds", "Kleinanzeigen");
//d.Add("windows", 5);
}
Now i want to access above defined dictionary from my main class for retrieving the keys and values of my Dictionary. Please Suggest me some code. I am using Visual C# 2008 Express Edition, Win Application
Declare Dictionary as class property.
public class Dict {
private Dictionary<string, string> dict;
public SomeDictionary { get dict; set dict = value; }
public Dict() {
dict = new Dictionary<string, string>();
dict.Add("Classifieds", "Kleinanzeigen");
}
}
In other class:
Dict d = new Dict();
string test = d.SomeDictionary["Classifieds"];
Console.WriteLine(test);
return the dictionary from the method.
public Dictionary<string, string> Dict() {.... ; return d;}
In your main class.
EngDictionary dict = new EngDictionary();
Dictionary<string, string> dictionary = dict.Dict();
You can declare Dictionary<string, string> d as a member variable of your class , and initialize this object in the class constructor.You can have a getter method to get the dictionary in other classes.
public class EngDictionary
{
Dictionary<string, string> dictionary;
public void EngDictionary()
{
dictionary = new Dictionary<string, string>();
dictionary.Add("Classifieds", "Kleinanzeigen");
....
}
public Dictionary<string, string> getDictionary()
{
return this.dictionary;
}
}
I have a class
public class Dict
{
public Dictionary<string, string> SomeDictionary { get; } = new Dictionary<string, string>()
{
{ "Classifieds", "Kleinanzeigen" }
};
}
then in any other class
Dict Dic = new Dict();
foreach (var item in Dic.SomeDictionary)
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}
If 'value' is an incoming generic dictionary whose types are unknown/don't matter, how do I take its entries and put them into a target dictionary of type IDictionary<object, object> ?
if(type == typeof(IDictionary<,>))
{
// this doesn't compile
// value is passed into the method as object and must be cast
IDictionary<,> sourceDictionary = (IDictionary<,>)value;
IDictionary<object,object> targetDictionary = new Dictionary<object,object>();
// this doesn't compile
foreach (KeyValuePair<,> sourcePair in sourceDictionary)
{
targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}
return targetDictionary;
}
EDIT:
Thanks for the responses so far.
The problem here is that the argument to Copy is only known as type 'object'. For example:
public void CopyCaller(object obj)
{
if(obj.GetType() == typeof(IDictionary<,>)
Copy(dictObj); // this doesn't compile
}
Make your method generic as well and then you'll be able to do what you're doing. You won't have to change your usage pattern since the compiler will be able to infer generic types from input types.
public IDictionary<object, object> Copy(IDictionary<TKey, TValue> source)
{
IDictionary<object,object> targetDictionary = new Dictionary<object,object>();
foreach (KeyValuePair<TKey, TValue> sourcePair in sourceDictionary)
{
targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}
return targetDictionary;
}
If you don't really need to convert it from IDictionary<TKey, TValue> to IDictionary<object, object> then you can use the copy constuctor of Dictionary<TKey, TValue> which accepts another dictionary as input and copies all values--just like you're doing now.
You can exploit the fact that generic dictionaries implement the IDictionary interface.
public static Dictionary<object, object> CreateCopy(IDictionary source)
{
var copy = new Dictionary<object, object>(source.Count);
foreach (DictionaryEntry entry in source)
{
copy.Add(entry.Key, entry.Value);
}
return copy;
}
Usage example:
var source = new Dictionary<int, string>() { { 1, "Foo" }, { 2, "Bar" }, };
var copy = CreateCopy(source);
Console.WriteLine(String.Join(", ", copy.Values));
Output:
Foo, Bar
Here is a method (don't leave it as static, unless you need it to be, I wrote it in a quick console app) that basically converts a Dictionary of any type to an object/object dictionary.
private static Dictionary<object,object> DeTypeDictionary<T,U>(Dictionary<T,U> inputDictionary)
{
Dictionary<object, object> returnDictionary = new Dictionary<object, object>();
foreach(T key in inputDictionary.Keys)
{
if( (key is object) && (inputDictionary[key] is object))
{
returnDictionary.Add(key, inputDictionary[key]);
}
else
{
//sorry these aren't objects. they may be dynamics.
continue;
}
}
return returnDictionary;
}
...and here is how you use it...
Dictionary<string, DateTime> d = new Dictionary<string, DateTime>();
d.Add("rsgfdg", DateTime.Now);
d.Add("gfdsgd", DateTime.Now);
Dictionary<object, object> newDictionary = DeTypeDictionary<string, DateTime>(d);
So you have an object that may be a Dictionary and you want to:
Test it's a dictionary
Act on it appropriately if it is
Let's start with a generic function that does what you want if you knew the type arguments:
class Bar
{
public static void Foo<TKey, TValue>(Dictionary<TKey, TValue> input) { ... }
}
Now we'll just have to do some reflection
bool TryHandleDictionary(object o)
{
var t = o.GetType();
if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Dictionary<,>)) return false;
var m = typeof(Bar).GetMethod("Foo", BindingFlags.Public | BindingFlags.Static);
var m1 = m.MakeGenericMethod(t.GetGenericArguments());
m1.Invoke(null, new[] { o });
return true;
}
This may be a fix for you but you'll need .net 3.5 or greater to use the var keyword.
// this should compile
foreach (var sourcePair in sourceDictionary)
{
targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}