Convert a list to a object c# - c#

I have a common method which accepts any paramater as object
public static object Populate(object anyStuff)
{
}
I to send a List of a user defined class to this. and then de serialize it again in the method to loop through it. I am not sure how to accomplish.

You can use Generics.
Where you can create the generic method that handles different type of list and operates on them:
public static T Populate<T>(List<T> list){
//Do stuff
}
But if you are using talking about object (do note, not a good way you are trying to achieve):
public static object Populate(object anyStuff){
//Explicit typecast
List<string> value = anyStuff as List<string>();
}
If you want to know the usage of the first example with generic, here you can see the example

Usually you would create multiple overloads of Populate.
If I read your question correctly, you'd like something like this:
var properties = new Dictionary<string, object>
{
{"Name", "Bart"},
{"Date", new DateTime(2014,9,23)},
{"Age", 300}
}
var item = HelperClass.Populate(properies)
Console.WriteLine(item.Name); // should print "bart"
If this is what you want, you should look into the dynamic ExpandoObject.
(see http://blog.jorgef.net/2011/06/converting-any-object-to-dynamic.html )
public static dynamic Populate(IDictionary<string, object> anystuff)
{
IDictionary<string, object> expando = new ExpandoObject()
foreach(var key in anystuff)
{
expando[key] = anystuff[key];
}
return expando;
}

Related

How can I refactor this C# code currently using Dictionarys to have even less redundancy and be more typesafe?

Because of business decisions which are above my paygrade, I need to parse and merge multiple XML files.
In order to cut down on redundant code, I have this map:
private static readonly Dictionary<string, Type> listTypeByFileName = new Dictionary<string, Type> {
{"a.xml", typeof(List<A>)},
{"b.xml", typeof(List<B>)},
{"c.xml", typeof(List<C>)},
{"d.xml", typeof(List<D>)},
// etc.
};
Because how this map gets used, after downloading and parsing all the XMLs, the result is of type Dictionary<string, object> where the key is the same as the keys in the above map and the value is of the type specified in the map, as result of executing this code with DownloadFiles(config):
private static Dictionary<string, object> DownloadFiles(IConfigurationRoot config) {
Dictionary<string, object> dataListByFileNames = new Dictionary<string, object>();
listTypeByFileName.Keys.ToList()
.ForEach(name => dataListByFileNames.Add(name, DownloadData(name, config)));
return dataListByFileNames;
}
private static object DownloadData(string name, IConfigurationRoot config) {
_ = listTypeByFileName.TryGetValue(name, out Type listType);
return new XmlSerializer(listType, new XmlRootAttribute("Document"))
.Deserialize(new StringReader(DownloadFromBlobStorage(name, config).ToString()));
}
private static CloudBlockBlob DownloadFromBlobStorage(string filetoDownload, IConfigurationRoot config) {
return CloudStorageAccount.Parse(config["AzureWebJobsStorage"])
.CreateCloudBlobClient()
.GetContainerReference(config["BlobStorageContainerName"])
.GetBlockBlobReference(filetoDownload);
First question: Is there a way I can make the return more typesafe? Perhaps using parameterized types?
The second part of the problem is actually consuming this Dictionary.
For each type in this Dictionary, I now need a function like:
private void AddA(Dictionary<string, object> dataByFileNames) {
if (dataByFileNames.TryGetValue("a.xml", out object data)) {
List<A> aList = (List<A>)data;
aList.ForEach(a =>
doSomethingWithA(a);
);
}
}
private void AddB(Dictionary<string, object> dataByFileNames) {
if (dataByFileNames.TryGetValue("b.xml", out object data)) {
List<B> bList = (List<B>)data;
bList.ForEach(b =>
doSomethingWithB(b);
);
}
}
// etc.
As I already have the list of filenames to types (top of this question), I feel there should be some way to abstract the above so it does not need to be repeated again and again and again.
Note, it may be significant that every type (A, B, C, D, etc. all have a property string Id which will be definitely be needed for all doStringWithX() methods... if useful, I can create an interface to get this. It is okay if I need to caste to the correct type within each doStringWithX() or when invoking each of these methods.c
First, instead of storing the List<T> type in the dictionary, just store the underlying generic type:
private static readonly Dictionary<string, Type> listTypeByFileName = new Dictionary<string, Type> {
{"a.xml", typeof(A)},
{"b.xml", typeof(B)}
// etc.
That's going to make future steps a little bit easier. When deserializing, create the generic list type. After getting the type from the dictionary, you can do:
var listType = typeof(List<>).MakeGenericType(typeRetrievedFromDictionary);
Once you've deserialized it, cast it as IList. That's effectively casting it as a list of object. That's okay. Because you deserialized using a specific type, every item in the list will be of the expected type.
Create a dictionary for the type-safe methods you want to invoke on every time in list.
Dictionary<Type, Action<object>> methodsToInvokeByType;
Add methods to the dictionary:
doSometingMethods.Add(typeof(A), dataItem => DoSomethingWithA((A)dataItem));
doSometingMethods.Add(typeof(B), dataItem => DoSomethingWithB((B)dataItem));
Now, once you've got your IList full of objects, you retrieve the type-safe method to invoke:
var methodToInvoke = methodsToInvokeByType[typeRetrievedFromDictionary];
Then do this:
foreach(object itemInList in list) // this is your deserialized list cast as IList
{
methodToInvoke(itemInList);
}
So if the type is A, you'll be invoking
DoSomethingWithA((A)itemInList)
It's not pretty. Bridging between code that uses objects and Type and type-safe generic code can be messy. But ultimately the goal is that whatever those final methods are - DoSomethingWithA, DoSomethingWithB, etc., at least those are type-safe.
You can simplify some more:
Create a class that deserializes a list and passes it off to a method for processing, and an interface:
public interface IXmlFileProcessor
{
void Process(byte[] xmlFile);
}
public class XmlFileProcessor<T> : IXmlFileProcessor
{
private readonly Action<T> _doSomething;
public XmlFileProcessor(Action<T> doSomething)
{
_doSomething = doSomething;
}
public void Process(byte[] xmlFile) // or string or whatever
{
// deserialize into a List<T>
foreach (T item in deserializedList)
_doSomething(item);
}
}
Then create a Dictionary<Type, IXmlFileProcessor> and populate it:
fileProcessors.Add(typeof(A), new XmlFileProcessor<A>(SomeClass.DoSomethingWithA));
fileProcessors.Add(typeof(B), new XmlFileProcessor<B>(SomeClass.DoSomethingWithB));
That approach (injecting the Action) is intended to keep the "do something" method decoupled from the class responsible for deserialization. DoSomething could also be a generic method in XmlFileProcessor<T>. There are different ways to compose those classes and add them to that dictionary. But either way, having determined the type, you just retrieve the correct type-specific processor from the dictionary, pass your file to it, and it does the rest.
That approach bridges the generic/non-generic gap by making the class - XmlFileProcessor<T> - generic, but having it implement a non-generic interface. It works as long as you take steps (using the dictionary) to ensure that you're selecting the correct implementation for whatever type you're deserializing.

Using Dictionary with nested Generics from Generic Method [duplicate]

I'd like to create a Dictionary object, with string Keys, holding values which are of a generic type. I imagine that it would look something like this:
Dictionary<string, List<T>> d = new Dictionary<string, List<T>>();
And enable me to add the following:
d.Add("Numbers", new List<int>());
d.Add("Letters", new List<string>());
I know that I can do it for a list of strings, for example, using this syntax:
Dictionary<string, List<string>> d = new Dictionary<string, List<string>>();
d.Add("Key", new List<string>());
but I'd like to do it for a generic list if possible...
2 questions then:
Is it possible?
What's the syntax?
EDIT: Now I've reread the question...
You can't do this, but a custom collection would handle it to some extent. You'd basically have a generic Add method:
public void Add<T>(string key, List<T> list)
(The collection itself wouldn't be generic - unless you wanted to make the key type generic.)
You couldn't extract values from it in a strongly typed manner though, because the compiler won't know which type you've used for a particular key. If you make the key the type itself, you end with a slightly better situation, but one which still isn't supported by the existing collections. That's the situation my original answer was responding to.
EDIT: Original answer, when I hadn't quite read the question correctly, but which may be informative anyway...
No, you can't make one type argument depend on another, I'm afraid. It's just one of the things one might want to express in a generic type system but which .NET's constraints don't allow for. There are always going to be such problems, and the .NET designers chose to keep generics relatively simple.
However, you can write a collection to enforce it fairly easily. I have an example in a blog post which only keeps a single value, but it would be easy to extend that to use a list.
Would something like this work?
public class GenericDictionary
{
private Dictionary<string, object> _dict = new Dictionary<string, object>();
public void Add<T>(string key, T value) where T : class
{
_dict.Add(key, value);
}
public T GetValue<T>(string key) where T : class
{
return _dict[key] as T;
}
}
Basically it wraps all the casting behind the scenes for you.
How about Dictionary<string, dynamic>? (assuming you're on C# 4)
Dictionary<string, dynamic> Dict = new Dictionary<string, dynamic>();
Source: https://stackoverflow.com/a/5038029/3270733
I prefer this way of putting generic types into a collection:
interface IList
{
void Add (object item);
}
class MyList<T> : List<T>, IList
{
public void Add (object item)
{
base.Add ((T) item); // could put a type check here
}
}
class Program
{
static void Main (string [] args)
{
SortedDictionary<int, IList>
dict = new SortedDictionary<int, IList> ();
dict [0] = new MyList<int> ();
dict [1] = new MyList<float> ();
dict [0].Add (42);
dict [1].Add ("Hello"); // Fails! Type cast exception.
}
}
But you do lose the type checks at compile time.
I came to a type safe implementation using ConditionalWeakTable.
public class FieldByType
{
static class Storage<T>
where T : class
{
static readonly ConditionalWeakTable<FieldByType, T> table = new ConditionalWeakTable<FieldByType, T>();
public static T GetValue(FieldByType fieldByType)
{
table.TryGetValue(fieldByType, out var result);
return result;
}
public static void SetValue(FieldByType fieldByType, T value)
{
table.Remove(fieldByType);
table.Add(fieldByType, value);
}
}
public T GetValue<T>()
where T : class
{
return Storage<T>.GetValue(this);
}
public void SetValue<T>(T value)
where T : class
{
Storage<T>.SetValue(this, value);
}
}
It can be used like this:
/// <summary>
/// This class can be used when cloning multiple related objects to store cloned/original object relationship.
/// </summary>
public class CloningContext
{
readonly FieldByType dictionaries = new FieldByType();
public void RegisterClone<T>(T original, T clone)
{
var dictionary = dictionaries.GetValue<Dictionary<T, T>>();
if (dictionary == null)
{
dictionary = new Dictionary<T, T>();
dictionaries.SetValue(dictionary);
}
dictionary[original] = clone;
}
public bool TryGetClone<T>(T original, out T clone)
{
var dictionary = dictionaries.GetValue<Dictionary<T, T>>();
if (dictionary == null)
{
clone = default(T);
return false;
}
return dictionary.TryGetValue(original, out clone);
}
}
See also this question where the type of the values is stored in as a generic parameter of the keys.
We're using lots of reflection to create an extensible administration tool. We needed a way to register items in the global search in the module definition. Each search would return results in a consistent way, but each one had different dependencies. Here's an example of us registering search for a single module:
public void ConfigureSearch(ISearchConfiguration config)
{
config.AddGlobalSearchCallback<IEmploymentDataContext>((query, ctx) =>
{
return ctx.Positions.Where(p => p.Name.Contains(query)).ToList().Select(p =>
new SearchResult("Positions", p.Name, p.ThumbnailUrl,
new UrlContext("edit", "position", new RouteValueDictionary(new { Id = p.Id }))
));
});
}
In the background during module registration, we iterate over every module and add the Func to a SearchTable with an instance of:
public class GenericFuncCollection : IEnumerable<Tuple<Type, Type, Object>>
{
private List<Tuple<Type, Type, Object>> objects = new List<Tuple<Type, Type, Object>>();
/// <summary>
/// Stores a list of Func of T where T is unknown at compile time.
/// </summary>
/// <typeparam name="T1">Type of T</typeparam>
/// <typeparam name="T2">Type of the Func</typeparam>
/// <param name="func">Instance of the Func</param>
public void Add<T1, T2>(Object func)
{
objects.Add(new Tuple<Type, Type, Object>(typeof(T1), typeof(T2), func));
}
public IEnumerator<Tuple<Type, Type, object>> GetEnumerator()
{
return objects.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return objects.GetEnumerator();
}
}
Then when we finally call it, we do it with reflection:
var dependency = DependencyResolver.Current.GetService(search.Item1);
var methodInfo = search.Item2.GetMethod("Invoke");
return (IEnumerable<SearchResult>)methodInfo.Invoke(search.Item3, new Object[] { query, dependency });
I didn't find what I was looking for here but after reading I think it might be what is being asked for so an attempt to answer.
The problem is that when you use Dictionary it is a closed constructed type and all elements must be of the TValue type. I see this question in a number of places without a good answer.
Fact is that I want indexing but each element to have a different type and based on the value of TKey we already know the type. Not trying to get around the boxing but trying to simply get more elegant access something like DataSetExtensions Field. And don't want to use dynamic because the types are known and it is just not wanted.
A solution can be to create a non generic type that does not expose T at the class level and therefore cause the TValue part of the dictionary to be closed constructed. Then sprinkle in a fluent method to help initialization.
public class GenericObject
{
private object value;
public T GetValue<T>()
{
return (T)value;
}
public void SetValue<T>(T value)
{
this.value = value;
}
public GenericObject WithValue<T>(T value)
{
this.value = value;
return this;
}
}
class Program
{
static void Main(string[] args)
{
Dictionary<string, GenericObject> dict = new Dictionary<string, GenericObject>();
dict["mystring"] = new GenericObject().WithValue<string>("Hello World");
dict["myint"] = new GenericObject().WithValue<int>(1);
int i = dict["myint"].GetValue<int>();
string s = dict["mystring"].GetValue<string>();
}
}
Other posibility it's to use the variable dynamic.
For example:
Dictionary<string, List<dynamic>> d = new Dictionary<string, List<dynamic>>();
d.Add("Key", new List<dynamic>());
the variable dynamic resolve the type on runtime.
No, but you can use object instead of generic type.
Long answer:
The current version of C# will not allow you to make entries of generic type in a dictionary. Your options are either a) create a custom class that is the same as a dictionary except allow it to accept generic types, or b) make your Dictionary take values of type object. I find option b to be the simpler approach.
If you send lists of specific types, then when you go to process the lists you will have to test to see what kind of list it is. A better approach is to create lists of objects; this way you can enter integers, strings, or whatever data type you want and you don't necessarily have to test to see what type of object the List holds. This would (presumably) produce the effect you're looking for.
Here is a short console program that does the trick:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace dictionary
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> dic = new Dictionary<string, object>();
var lstIntList = new List<object>();
var lstStrings = new List<object>();
var lstObjects = new List<object>();
string s = "";
lstIntList.Add(1);
lstIntList.Add(2);
lstIntList.Add(3);
lstStrings.Add("a");
lstStrings.Add("b");
lstStrings.Add("c");
dic.Add("Numbers", lstIntList);
dic.Add("Letters", lstStrings);
foreach (KeyValuePair<string, object> kvp in dic)
{
Console.WriteLine("{0}", kvp.Key);
lstObjects = ((IEnumerable)kvp.Value).Cast<object>().ToList();
foreach (var obj in lstObjects)
{s = obj.ToString(); Console.WriteLine(s);}
Console.WriteLine("");
}
Console.WriteLine("");
Console.WriteLine("press any key to exit");
Console.ReadKey();
}//end main
}
}
One of the way is to create a Dictionary value with type "object" like:
Dictionary<string, object> d = new Dictionary<string, object>();
So, here object datatype is used as a generic datatype, you can put anything in this as a value.
Or it's possible to use generic Type like this
public static void SafeUpdateInDictionary<T, L>(T DictionaryToBeUpdated, string Key, L Value) where T : Dictionary<string, L>
{
if (DictionaryToBeUpdated != null)
{
if(Value != null)
{
if (!DictionaryToBeUpdated.ContainsKey(Key))
DictionaryToBeUpdated.Add(Key, Value);
else
DictionaryToBeUpdated[Key] = Value;
}
}
}

Is it possible to create a method that returns one of two possible types?

I have 2 data structures: Dictionary<string, string> and Multimap<string, string>.
Multimap is really just a Dictionary under the hood. I took must of the code from this question. Here's the class definition:
public class Multimap<TKey, TValue> : Dictionary<TKey, HashSet<TValue>>
{ ... }
Both data structures have a .Add(TKey key, TValue value) method.
I have a class that is responsible for populating these maps from certain files. I currently have the following two methods:
public Dictionary<string, string> PopulateDictionary(...)
{
Dictionary<string, string> returnDictionary = new Dictionary<string, string>();
...
foreach (...)
{
...
returnDictionary.Add(key, value);
}
return returnDictionary;
}
public Multimap<string, string> PopulateMultimap(...)
{
Multimap<string, string> returnMultimap = new Multimap<string, string>();
...
foreach (...)
{
...
returnMultimap.Add(key, value);
}
return returnMultimap;
}
As you can see, they're exactly the same, both around 25 lines long, and the only difference is their return type. What I am looking to do is condense this into one method.
My first attempt was to have the method
public Dictionary<string, object> PopulateGenericDictionary(...)
{ ... }
Where object was either string or HashSet<string>. But I didn't have much luck casting from Dictionary<string, object> to Multimap<string, string>.
Extracting the logic out of the methods is an option, but it's not great. Because of the foreach loops, there's always going to be some logic inside the two methods. You do end up with methods that are twice as small, but there's still two identical methods, which doesn't truly solve the problem.
This would be my ideal method structure:
public Dictionary<string, string> PopulateDictionary(...)
{
return MethodThatDoesAllTheLogic(...);
}
public Multimap<string, string> PopulateMultimap(...)
{
return MethodThatDoesAllTheLogic(...);
}
public ??? MethodThatDoesAllTheLogic(...)
{ ... }
I've been fiddling around with casting and generics, but I just can't get it to work. Any ideas?
Edit
I have used millimoose's solution. Here's my code now:
public Dictionary<string, string> GenerateDictionary(...)
{
Dictionary<string, string> returnMap = new Dictionary<string, string>();
PopulateDictionary(returnMap.Add, ...);
return returnMap;
}
public Multimap<string, string> GenerateMultimap(...)
{
Multimap<string, string> returnMap = new Multimap<string, string>();
PopulateDictionary(returnMap.Add, ...);
return returnMap;
}
private static void PopulateGenericDictionary(Action<string, string> addFunc, ...)
{
...
foreach (...)
{
addFunc(key, value);
}
}
Much cleaner!
To work around the lack of a common interface, you can invent one ad-hoc using a bunch of delegate type parameters:
void MethodThatDoesAllTheLogic(Action<string, string> addFunc)
{
// ...
addFunc(key, value);
// ...
}
public Dictionary<...> PopulateDictionary()
{
// ...
MethodThatDoesAllTheLogic(result.Add);
}
(Adding more parameters as necessary.)
I would avoid having the helper method create the actual collection at all; have it just populate an existing collection. That can be done much more effectively, since the Add method has the same signature in both cases. We can just use a delegate to accept the Add method:
public static void PopulateMapping<TKey, TValue>(Action<TKey, TValue> addMethod,
IEnumerable<TKey> data) //include other parameters needed to populate the data
{
foreach (var key in data)
{
addMethod(key, default(TValue));
}
}
Then it would be used like this:
public static Dictionary<string, string> PopulateDictionary()
{
Dictionary<string, string> output = new Dictionary<string, string>();
PopulateMapping<string, string>(output.Add, new string[] { "a" });
return output;
}
If you are only looking for an Add method, then both objects should share IDictionary. However, that Add method only uses objects. That is probably the closest that you can get without having to use generics in the method...but again you lose the benefits of generics at that point.
See if this approach will be useful:
The key is to make abstraction on creation of the object (Dictionary or Multimap) and aquiring the values - the two differences in the populating method.
public Dictionary<string, TValue> Populate<TValue>( Dictionary<string, TValue> returnDict, Func<SomeType, TValue> valueProvider)
{
string key = null;
...
foreach (...)
{
...
returnDict.Add(key, valueProvider(value));
}
return returnDict;
}
The example invocation is can be:
public void Test()
{
Populate(new Multimap<string, HashSet<string>>(), (t) => new HashSet<HashSet<string>>());
}
I'm not sure if the valueProvider delegate will be suited to your problem. Try to give more information about it.
If your inner logic is truly identical except for what type TValue is - and I mean word-for-word identical - then you could do something like:
IDictionary<string, TValue> MethodThatDoesAllTheLogic<TValue>(whatever)
{
// word for word-identical logic
}
I made the method take TValue as its only type parameter because that's the only difference (in the example you showed): both methods have string as the first type parameter.
ETA: This assumes that MultiMap implements IDictionary<K,V>. Since you said that it inherited from Dictionary<K,V> I assumed that it did.
in C# with generics you can require them to extend or implement a specific class in our case Dictionary, the following is how you might achieve that.
public T Populate<T>(string val) where T : Dictionary<string, string>, new()
{
T returnDict = new T();
returnDict.Add("key", "val");
return returnDict;
}

How can i pass Dictionary<string, string> to a dictionary<object,object> method?

How can i pass a Dictionary to a method that receives a Dictionary?
Dictionary<string,string> dic = new Dictionary<string,string>();
//Call
MyMethod(dic);
public void MyMethod(Dictionary<object, object> dObject){
.........
}
You cannot pass it as is, but you can pass a copy:
var copy = dict.ToDictionary(p => (object)p.Key, p => (object)p.Value);
It is often a good idea to make your API program take an interface rather than a class, like this:
public void MyMethod(IDictionary<object, object> dObject) // <== Notice the "I"
This little change lets you pass dictionaries of other kinds, such as SortedList<K,T> to your API.
If you want to pass dictionary for read-only purposes, then you could use Linq:
MyMethod(dic.ToDictionary(x => (object)x.Key, x => (object)x.Value));
Your current aproach does not work due to type-safe restrictions:
public void MyMethod(Dictionary<object, object> dObject){
dObject[1] = 2; // the problem is here, as the strings in your sample are expected
}

Having trouble with Generics in this .NET code

i'm trying to make a mixed collection of Types. I know the types at the start.. but I can't seem to figure out the syntax to make the collection, etc.
eg.
....
// I leave the typo there, for embarrassment :(
Initialize(new []{ typeof(Cat), typeof(Dog), typeof(JohnSkeet) });
...
public Foo Initialize(IEnumerable<Type> types)
{
// for each type, set up the inmemory storage.
foreach(var type in types)
{
// ????
// Create an empty list, which will only contain this 'type'
// I'm guessing, an IDictionary<type, ICollection<type>>().. thingy ?
}
}
public ICollection<Type> SomeTypeData(Type type)
{
// Return the collection, for this type.
}
Does this mane sense? Is this possible?
Okay, now that I think I know what you want, it would look something like this:
// This can't really be *properly* statically typed
private readonly Dictionary<Type, object> typeMap = new
Dictionary<Type, object>();
public Foo Initialize(IEnumerable<Type> types)
{
Type genericListType = typeof(List<>);
foreach(var type in types)
{
// MakeGenericType is really badly named
Type constructedListType = genericListType.MakeGenericType(type);
typeMap[type] = Activator.CreateInstance(constructedListType);
}
}
// We can't express this particularly safely either,
// although we *could* return the non-generic IList
public object SomeTypeData(Type type)
{
return typeMap[type];
}
// This *is* statically typed, although we need to cast inside
public IList<T> SomeTypeData<T>()
{
return (IList<T>) typeMap[typeof(T)];
}
See this blog post for a similar example.
Note that basically you're trying to represent something which generics simply can't handle, in terms of the internal dictionary type... and the first form of SomeTypeData can't be statically typed either... because that means knowing the type at compile time when we'll only actually be given it at execution time.
It looks to me like you're trying to create some kind of instance repository; a class that stores a list of instances of a given type.
Here's an example implementation. I've included both a generic and non-generic version of the SomeTypeData method:
public class InstanceRepository
{
private IDictionary<Type, ICollection> _Instances = new Dictionary<Type, ICollection>();
public ICollection SomeTypeData(Type type)
{
ICollection instanceList;
if (!_Instances.TryGetValue(type, out instanceList))
{
// this type does not exist in our dictionary, so let's create a new empty list
// we could do this:
//instanceList = new List<object>();
// but let's use reflection to make a more type-specific List<T> instance:
instanceList = (ICollection)Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
// now add it to the dictionary
_Instances.Add(type, instanceList);
}
// Return the collection, for this type.
return instanceList;
}
public IList<T> SomeTypeData<T>()
{
Type type = typeof(T);
ICollection instanceList;
if (!_Instances.TryGetValue(typeof(T), out instanceList))
{
instanceList = new List<T>();
_Instances.Add(type, instanceList);
}
// here we are assuming that all of the lists in our dictionary implement IList<T>.
// This is a pretty safe assumption, since the dictionary is private and we know that
// this class always creates List<T> objects to put into the dictionary.
return (IList<T>)instanceList;
}
}
Below is a usage example:
Generic:
InstanceRepository repository = new InstanceRepository();
var listOfCats = repository.SomeTypeData<Cat>();
listOfCats.Add(new Cat());
Cat firstCat = listOfCats[0];
Console.WriteLine(listOfCats.GetType().FullName);
Non-Generic:
InstanceRepository repository = new InstanceRepository();
var listOfCats = (IList<Cat>)repository.SomeTypeData(typeof(Cat));
listOfCats.Add(new Cat());
Cat firstCat = listOfCats[0];
Console.WriteLine(listOfCats.GetType().FullName);
I guess you want something like
_dict[typeof(Cat)]=new List<Cat>();
_dict[typeof(Dog)]=new List<Dog>();
only programatically based on given types?
Something like this should work:
public void Initialize(IEnumerable<Type> types)
{
foreach(var type in types)
{
var list = Activator.CreateInstance(Type.GetType("System.Collections.Generic.List`1").MakeGenericType(type));
_cache[type] = list;
}
}
public ICollection<T> Get<T>()
{
object list;
if (_cache.TryGetValue(typeof(T), out list)
{
return list as ICollection<T>;
}
else
{
...
}
}
var cats = Get<Cat>();
I'm not sure I fully understand you're question, but if you already have an IEnumerable<Type> which contains an enumeration of Type objects, then why not just use that to initialize some type of Collection (such as List<Type>)?
public ICollection<Type> Initialize(IEnumerable<Type> types)
{
ICollection<Type> collection = new List<Type>(types);
return collection;
}

Categories