How to retrieve Object and its member from arraylist in c#.
You mean like this?
ArrayList list = new ArrayList();
YourObject myObject = new YourObject();
list.Add(myObject);
YourObject obj = (YourObject)list[0];
To loop through:
foreach(object o in list)
{
YourObject myObject = (YourObject)o;
.......
}
Information on ArrayList
object[] anArray = arrayListObject.ToArray();
for(int i = 0; i < anArray.Length; i++)
Console.WriteLine(((MyType)anArray[i]).PropertyName); // cast type MyType onto object instance, then retrieve attribute
Here's an example of a simple ArrayList being populated with a new KeyValuePair object. I then pull the object back out of the ArrayList, cast it back to its original type and access it property.
var testObject = new KeyValuePair<string, string>("test", "property");
var list = new ArrayList();
list.Add(testObject);
var fetch = (KeyValuePair<string, string>)list[0];
var endValue = fetch.Value;
You should use generic collections for this. Use the generic ArrayList so you dont have to cast the object when you are trying to get it out of the array.
You can also use extension methods:
ArrayList list = new ArrayList();
// If all objects in the list are of the same type
IEnumerable<MyObject> myenumerator = list.Cast<MyObject>();
// Only get objects of a certain type, ignoring others
IEnumerable<MyObject> myenumerator = list.OfType<MyObject>();
Or if you're not using a newer version of .Net, check the object type and cast using is/as
list[0] is MyObject; // returns true if it's an MyObject
list[0] as MyObject; // returns the MyObject if it's a MyObject, or null if it's something else
Edit: But if you're using a newer version of .Net...
I strongly suggest you use the Generic collections in System.Collections.Generic
var list = new List<MyObject>(); // The list is constructed to work on types of MyObject
MyObject obj = list[0];
list.Add(new AnotherObject()); // Compilation fail; AnotherObject is not MyObject
Do a type casting like this:
yourObject = new object[]{"something",123,1.2};
((System.Collections.ArrayList)yourObject)[0];
Related
i have a variable swimlaneAttribute:
List<dynamic> swimlaneAttributes = new List<dynamic>();
but in a function i have a return type of dynamic
public dynamic GetSwimlaneAttribute(List<ProjectSwimlaneAttribute> swimlaneAttributeTable, Dictionary<string, string> dic)
{
dynamic swimlaneAttributes = null;
swimlaneAttributes = swimlaneAttributeTable.Select(s => new
{
ID = s.Id,
DataType = s.AttributeDataType,
IsCriticalField = s.IsCriticalField,
});
return swimlaneAttributes;
}
this will return some records from table parameter that i am passing!!
now i have to call this GetSwimlaneAttribute function, in return i will get all the required records(from a table)
but when i pass this to swimlaneAttributes it goes to catch block!!!
swimlaneAttributes = GetSwimlaneAttribute();
if i pass it this way, (i think the record count becomes 0)
//swimalneAttributes = GetSwimlaneAttribute as List<dynamic>;
So how to convert Dynamic to List
Thanks!
You're currently returning a sequence of anonymous type objects. That sequence can't be cast to a List<T> because it isn't a List<T>.
You could change the declaration to:
IEnumerable<dynamic> GetSwimlaneAttribute(...)
with no change to the body of the code - then to get a List<dynamic> just call it as:
List<dynamic> list = GetSwimlaneAttribute(...).ToList();
If you absolutely can't change the declaration, you could convert it outside the method:
IEnumerable<dynamic> sequence = GetSwimlaneAttribute(...);
List<dynamic> list = sequence.ToList();
Or call the extension method directly:
List<dynamic> list = Enumerable.ToList<dynamic>(GetSwimlaneAttirbute(...));
However, you should be aware that anonymous types don't cross assembly boundaries (without a bit of hackery). You should strongly consider creating a named type for this instead.
Additionally, your method body is a bit crufty - you declare a variable and assign it a null value, then immediately assign a different value, and then just return that value. The whole thing could be written as:
return swimlaneAttributeTable.Select(s => new
{
ID = s.Id,
DataType = s.AttributeDataType,
IsCriticalField = s.IsCriticalField,
});
How about this one?
List<dynamic> lstDynamic = new List<dynamic>();
lstDynamic.Add(GetSwimlaneAttribute());
and use lstDynamic.
why don't you try this way?
public List<dynamic> GetSwimlaneAttribute(List<ProjectSwimlaneAttribute> swimlaneAttributeTable, Dictionary<string, string> dic)
{
List<dynamic> swimlaneAttributes = new List<dynamic>(); // modified dynamic to List<dynamic>
swimlaneAttributes = swimlaneAttributeTable.Select(s => new
{
ID = s.Id,
DataType = s.AttributeDataType,
IsCriticalField = s.IsCriticalField,
});
return swimlaneAttributes;
}
I know I can create an object whose type is known only at run time like this:
Type t = record.GetType();
var src = Activator.CreateInstance(t.BaseType);
How can I do something like List<Record>=new List<Record>() at run time?
Suppose I am getting Child Record list using Reflection like this
var ChildRecorList=src.GetType().GetProperty(propName).GetValue(src, null);
and how can then I loop through this using foreach or for loop because foreach only works for known type list. It does now work with var types. Is there way to cast Reflection value to cast at specific type whose value is known at runtime(mentioned in point 1)
You can try this to create generic type in runtime:
Type genericListType = typeof (List<>);
// if you have more than one generic argumens
// you can add your types here like typeof(MyClass),typeof(MyClass2)
Type[] genericArguments = { typeof (Record) };
// create your generic type with generic arguments
Type myGenericType = genericListType.MakeGenericType(genericArguments);
// and then you can create your instance
var recordList = Activator.CreateInstance(myGenericType);
// get your property value
recordList = src.GetType().GetProperty(propName).GetValue(src, null);
And I guess you sure your type is a List then when you creating your instance you can make a cast like this:
var recordList = (IList)Activator.CreateInstance(myGenericType);
Then you can loop through your list
foreach (var item in recordList)
{
...
}
I'm not sure If you're looking for something like this, But you can use List Inside another List or Dictionary, Also, You can store the base value with any type and get the type whenever needed, I recommend using Dictionary so that way you can name your lists:
Dictionary<String, List<Object>> Data = new Dictionary<String, List<Object>>();
Data["MyUser"] = new List<Object>();
Data["MyUser"].Add(MyDBObject);
var obj = Data["MyUser"].Find(x => x.MyKey == "MyKeyObject");
var t = obj.GetType();
var dta = (MyDBObject)obj;
foreach (var db in Data)
{
if (db.Key == "MyUser")
db.Value.Find(x => x.Name == "MyName");
}
Or If you're looking for Creating lists on runtime:
List<List<Object>> Data = new List<List<Object>>();
var mydb = Data.Count;
Data.Add(new List<Object>());
Data[mydb].Add(MyOBJ);
foreach (var db in Data)
{
if (db.Contains(MyOBJ)
return db;
}
Why don't you just use generics? You could do something like this:
public void DoSomething<T>(T type)
{
var list = new List<T>();
}
This will allow you to create a list from whichever type is passed in at runtime.
In a method, I get an object.
In some situation, this object can be an IList of "something" (I have no control over this "something").
I am trying to:
Identify that this object is an IList (of something)
Cast the object into an "IList<something>" to be able to get the Count from it.
For now, I am stuck and looking for ideas.
You can check if your object implements IList using is.
Then you can cast your object to IList to get the count.
object myObject = new List<string>();
// check if myObject implements IList
if (myObject is IList)
{
int listCount = ((IList)myObject).Count;
}
if (obj is ICollection)
{
var count = ((ICollection)obj).Count;
}
object o = new int[] { 1, 2, 3 };
//...
if (o is IList)
{
IList l = o as IList;
Console.WriteLine(l.Count);
}
This prints 3, because int[] is a IList.
Since all you want is the count, you can use the fact that anything that implements IList<T> also implements IEnumerable; and furthermore there is an extension method in System.Linq.Enumerable that returns the count of any (generic) sequence:
var ienumerable = inputObject as IEnumerable;
if (ienumerable != null)
{
var count = ienumerable.Cast<object>().Count();
}
The call to Cast is because out of the box there isn't a Count on non-generic IEnumerable.
I have an ArrayList of objects that are of a certain type, and I need to convert this ArrayList in to a types list. Here is my code
Type objType = Type.GetType(myTypeName);
ArrayList myArrayList = new ArrayList();
object myObj0 = Activator.CreateInstance(type);
object myObj1 = Activator.CreateInstance(type);
object myObj2 = Activator.CreateInstance(type);
myArrayList.Add(myObj0);
myArrayList.Add(myObj1);
myArrayList.Add(myObj2);
Array typedArray = myArrayList.ToArray(objType); // this is typed
object returnValue = typedArray.ToList(); // this is fake, but this is what I am looking for
There is no ToList() available for an Array, this is the behaviour I am looking for
object returnValue = typedArray.ToList();
So basically I have the type name as a string, I can create a Type from the name, and create a collection containing several objects typed, but how do I convert that to a List? I am hydrating a property and when I do a SetValue my property type needs to match.
Thank you very much.
If you're using .NET 4, dynamic typing can help - it can perform type inference so you can call ToList, admittedly not as an extension method:
dynamic typedArray = myArrayList.ToArray(objType);
object returnValue = Enumerable.ToList(typedArray);
Otherwise, you'll need to use reflection:
object typedArray = myArrayList.ToArray(objType);
// It really helps that we don't need to work through overloads...
MethodInfo openMethod = typeof(Enumerable).GetMethod("ToList");
MethodInfo genericMethod = openMethod.MakeGenericMethod(objType);
object result = genericMethod.Invoke(null, new object[] { typedArray });
Create a
List<YourType> list = new List<YourType>;
and then
list.AddRange(yourArray);
Use an extenstion method: .ToList<myType>()
Use the generic List<> type instead.
Does it have to be List<T> or would an IEnumerable<T> do?
Taking a little from Linq you could do:
object returnValue = myArrayList.Cast<string>();
Which creates the following object (assuming T = string):
System.Linq.Enumerable+<CastIterator>d__b1`1[System.String]
I know this does not work, however does anyone have a way of making it work?
object obj = new object();
MyType typObj = new MyType();
obj = typObj;
Type objType = typObj.GetType();
List<objType> list = new List<objType>();
list.add((objType) obj);
EDIT:
Here is the current code: http://github.com/vimae/Nisme/blob/4aa18943214a7fd4ec6585384d167b10f0f81029/Lala.API/XmlParser.cs
The method I'm attempting to streamline is SingleNodeCollection
As you can see, it currently uses so hacked together reflection methods.
It seems you're missing an obvious solution:
object obj = new object();
MyType typObj = new MyType();
obj = typObj;
List<MyType> list = new List<MyType>();
list.Add((MyType) obj);
If you really need the dynamic route, then you could do something like this:
object obj = new object();
MyType typObj = new MyType();
obj = typObj;
Type objType = typObj.GetType();
Type listType = typeof(List<>);
Type creatableList = listType.MakeGenericType(objType);
object list = Activator.CreateInstance(creatableList);
MethodInfo mi = creatableList.GetMethod("Add");
mi.Invoke(list, new object[] {obj});
You need reflection:
constructor = typeof (MyType).GetConstructor () // doing this from memory, the typeof might be wrong, I'm sure someone will edit it
typObj = (MyType) constructor.Invoke ()
It can also be done for generics but that is a bit trickier.
You can do something like this using Generics, I'm not really sure what the point of it would be though.
public List<T> TypedList<T>() where T : new()
{
object obj = new object();
T typObj = new T();
obj = typObj;
List<T> list = new List<T>();
list.Add((T)obj);
return list;
}
object obj = new object();
Type objType = obj.GetType();
IList list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(objType));
list.Add(obj);
With this you will get an runtime error if you try to put something into list that is not assignable from objType.
Even though it seems answered, I still don't get it :)
Wouldn't it be useful to have the "typeToReturn" as generic argument to the function?
public List<T> SingleNodeCollection<T>(String xPath, XPathNavigator navigator)
where T : new()
{
XPathNodeIterator nodes = navigator.Select(xPath);
List<T> returnedList = new List<T>(nodes.Count);
...
T newObj = new T();
...
Type t = typeof(T); // need the type anyway?
}
public class myClass
{
}
myClass instance = new myClass();
Type t = instance.GetType;
//top is just to show obtaining a type...
public object GetListOfType(Type t)
{
Type listType = typeof(List<>);
var listOfType = listType.MakeGenericType(t);
var listOfMyClassInstance = Activator.CreateInstance(listOfType);
return listOfMyClassInstance;
}
but eventually you have to cast... using your type directly
List<object> listOfMyClass = GetListOfType(t);
listOfMyClass.Add(myClassInstance);
((myClass)listOfMyClass[0]).SomeProperty
Faster would be to use Reflection.Emit
Here's a simple example of using Reflection.Emit for instantiating an arbitrary concrete type at runtime. For your purposes, you just need to have it call the ctor of List instead of T.ctor as in the example.
I'm not entirely sure what you are trying to do, but would this work:
var obj = new MyType();
I might be misunderstanding your question though.
(I edited this to fix sample code which wouldn't compile, thanks for the comment)