I am trying to do the following but I think I must be missing something...(fairly new to generics)
(Need to target .NET 2.0 BTW)
interface IHasKey
{
string LookupKey { get; set; }
}
...
public static Dictionary<string, T> ConvertToDictionary(IList<T> myList) where T : IHasKey
{
Dictionary<string, T> dict = new Dictionary<string, T>();
foreach(T item in myList)
{
dict.Add(item.LookupKey, item);
}
return dict;
}
Unfortunately, this gives a "Constraints are not allowed on non-generic declarations" error. Any ideas?
You have not declared the generic parameter.
Change your declaration to:
public static Dictionary<string, T> ConvertToDictionary<T> (IList<T> myList) where T : IHasKey{
}
Try something like this
public class MyObject : IHasKey
{
public string LookupKey { get; set; }
}
public interface IHasKey
{
string LookupKey { get; set; }
}
public static Dictionary<string, T> ConvertToDictionary<T>(IList<T> myList) where T: IHasKey
{
Dictionary<string, T> dict = new Dictionary<string, T>();
foreach(T item in myList)
{
dict.Add(item.LookupKey, item);
}
return dict;
}
List<MyObject> list = new List<MyObject>();
MyObject o = new MyObject();
o.LookupKey = "TADA";
list.Add(o);
Dictionary<string, MyObject> dict = ConvertToDictionary(list);
You forgot the Generic Paramter in the method
public static Dictionary<string, T> ConvertToDictionary<T>(IList<T> myList) where T: IHasKey
Since the classes in the input list are different (as you say in your comment) you can either implement it like suggested by #orsogufo, or you could just as well implement your signature on the interface itself:
public static Dictionary<string, IHasKey> ConvertToDictionary(IList<IHasKey> myList)
{
var dict = new Dictionary<string, IHasKey>();
foreach (IHasKey item in myList)
{
dict.Add(item.LookUpKey, item);
}
return dict;
}
Using the generic declaration is best if you have a list of one specific implementation of the interface as noted in the comments to the other answer.
Related
I have some classes which have a large number of properties of varying types: e.g. 15 properties, some string, some int, some enum and some custom types.
In order to "mange" and "interact" with them without requiring lots of constructor overloads and stuff I am currently using a Dictionary<string, string> in my getters and setters. For example:
{
public IDictionary<string, string> Attributes
{
get
{
Dictionary<string, string> atts = new Dictionary<string, string>(15);
atts.Add("Prop1", Prop1.ToString());
atts.Add("Prop2", Prop2);
...
}
set
{
IDictionary<string, string> atts = value;
foreach (KeyValuePair<string, string> att in atts)
switch (att.Key) // Yeah I know latest C# has more concise syntax
{
case "Prop1":
Prop1 = att.Value;
break;
...
}
}
}
}
I did also come up with a slightly less verbose way using reflection:
public Dictionary<string, object> GetProperties()
{
Dictionary<string, object> dict = new Dictionary<string, object>();
Type t = typeof(MyClass);
PropertyInfo[] props = t.GetProperties();
foreach (var prop in props)
{
dict.Add(prop.Name, prop.GetValue(this));
}
return dict;
}
public void SetProperties(Dictionary<string, object> props)
{
foreach (var prop in props)
{
var propToSet = this.GetType().GetProperty(prop.Key);
propToSet.SetValue(this, prop.Value);
}
}
Obviously I can also use constructor initialization like:
MyClass myClass = new()
{
Prop1 = ...,
Prop2 = ...
...
}
I just wonder if there's any other elegant solutions out there?
You can convert the object to Json then Deserialize it to dictionary
public static Dictionary<string, object> ToDictionary(object model)
{
var serializedObj = JsonModelSerializer.Serialize(model);
return JsonModelSerializer.Deserialize<Dictionary<string, object>>(serializedObj);
}
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 want to implement a wrapper class for a Dictionary that maps a Type to a generic List of that Type. For example:
**Key** **Value**
typeof(InterfaceA), List<InterfaceA>
typeof(InterfaceB), List<InterfaceB>
typeof(MyClass), List<MyClass>
...
I then want to interact with the wrapper class by using types.
public void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry<T>()
{
return MyDict[typeof(T)];
}
public void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
Is there any elegant way to do this?
EDIT: to clarify, the point of this is so that with
GetEntry<MyInterface>()
the items in the list are guaranteed to follow the contract of MyInterface. Each entry would have a different Type key, and each List of items would follow the contract of that Type.
You could use the following static class
public static class GenericLists
{
private static Dictionary<Type, object> MyDict = new Dictionary<Type, object>();
public static void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public static List<T> GetEntry<T>()
{
return (List<T>)MyDict[typeof(T)];
}
public static void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
}
Or you could use
public class GenericLists<T>
{
private Dictionary<Type, List<T>> MyDict = new Dictionary<Type, List<T>>();
public void NewEntry()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry()
{
return MyDict[typeof(T)];
}
public void RemoveEntry()
{
MyDict.Remove(typeof(T));
}
}
if you really want to initialize it, but I think the static will work better.
If you're willing to store everything statically, you can use the type system:
static class MyDict {
private static class Data<T> {
public static readonly List<T> items = new List<T>();
}
public static List<T> Get<T>() { return Data<T>.items; }
public static void Add<T>(T item) { Data<T>.items.Add(item); }
}
Note that this makes it impossible to remove a key (you can't unload a type), although you can Clear() it.
You can do it as an instance-based class also (see below), but my preference, if it works for you, is to use a static variable in a static class as SLaks demonstrated in the "use the type system" post.
public class GenericTypeListDictionary
{
private readonly Dictionary<Type, object> _dictionaryOfLists = new Dictionary<Type, object>();
public List<T> NewEntry<T>()
{
var newList = new List<T>();
_dictionaryOfLists.Add(typeof(T), newList);
return newList;
}
public List<T> GetEntry<T>()
{
object value;
if (_dictionaryOfLists.TryGetValue(typeof(T), out value))
{
return (List<T>)value;
}
return null;
}
public void RemoveEntry<T>()
{
_dictionaryOfLists.Remove(typeof(T));
}
}
I'm newb with generics/iterators/enumerators etc.
I have code, it keeps field number (int) and error mesages (List string) for each field:
public class ErrorList : IEnumerable // ?
{
private Dictionary <int, List<string>> errorList;
// ...
}
How to make this class work with foreach loop? I wanna use GetEnumerator form Dictionary, but how should i do this?
You could simply provide a public GetEnumerator method:
public class ErrorList
{
private Dictionary<int, List<string>> errorList = new Dictionary<int, List<string>>();
... some methods that fill the errorList field
public IEnumerator<KeyValuePair<int, List<string>>> GetEnumerator()
{
return errorList.GetEnumerator();
}
}
and now assuming you have an instance of ErrorList:
var errors = new ErrorList();
you can loop through them:
foreach (KeyValuePair<int, List<string>> item in errors)
{
...
}
Dictionary implements IEnumerable<KeyValuePair<TKey, TValue>>, so this works:
foreach (KeyValuePair<Int, List<String>> kvp in errorList) {
var idx = kvp.Key;
var vals = kvp.Value;
// ... do whatever here
}
You can simply return errorList.GetEnumerator().
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);
}