//Data is IList<ExpandoObject>
var result = (from dynamic item in Data
where item.id== "123"
select item).FirstOrDefault();
Want to achieve below feature but it is erroring out by saying remove not available for dynamic objects.
Data.Remove(result);
Let me know if any suggestions.
thanks
Error: remove not available for dynamic objects
base on Microsoft's docs, The Remove method of IList<T> accepts a parameter with the type of T:
ICollection<T>.Remove(T)
In your example, T is an ExpandoObject, so it means in the Remove method you should pass a parameter with the type of ExpandoObject but you didn't and you are passing a parameter with the type of dynamic. Therefore you facing this error
for resolving this you have two way:
1) Use explicit type instead of var:
ExpandoObject result = ...
2) cast the result when you are passing it to Remove:
Data.Remove((ExpandoObject) result)
I think with doing one of these ways, your problem will resolve. good luck.
Related
In one of my classes I have the following property:
public List<ClassP> MyPlanes { get; set; }
In another method I have a the propertyInfo of the property above (the function self does not know where the propertyinfo comes from). Right now i'm trying to create a list of classP when i only have the propertyInfo of MyPlanes. So far my attempts seem to be in vain, this is howfar i got sofar:
variable prop is the PropertyInfo of MyPlanes
public void GenerateList(PropertyInfo prop)
{
if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericArguments().Length > 0)
{
List<prop.PropertyType.GetGenericArguments().First()> myValueList =
new List<prop.PropertyType.GetGenericArguments().First()>();
}
}
The creating of the list (with the code above) gives the following error Using the generic type 'System.Collections.Generic.List<T>' requires 1 type arguments
Any help would be greatly appreciated
Note: I want the list creating in a syntax (or a syntax similar) as visible above. I want to keep my code as generic as possible
To make a generic class when you have the type, you can't use the brackets <> because you don't know the type at compile time. You need to do something like this:
var baseType = typeof(List<>);
var genericType = baseType.MakeGenericType(prop.PropertyType.GetGenericArguments().First());
Now you have the correct type and you can create it like so:
IList myList = (IList)Activator.CreateInstance(genericType);
Edit: although as Selman22 says above, you already have the PropertyType, so you don't need to get the generic type unless you are trying to make a different generic class with the same generic argument (say you have a List<T> and need to make a Dictionary<Type,T> or something). So I'll leave my answer in case you encounter that situation.
Unfortunutely, it does not work like that.You need to use Reflection to create a new instance as well:
var list = (List<ClassP>)Activator.CreateInstance(prop.PropertyType);
CreateInstance method returns object. If you don't know the type at compile time, there is no way to cast it. Best thing you can to would be using dynamic.And that way you can access any members without any compile time error, but clearly it's not safe.
You should probably reconsider whether you really need to use Reflection here.If your problem can be solved without using Reflection then you should go with that way.
public T getValueByName<T>(String name)
{
if( T is List )
Object containedType = T.WhatGoesHere()?
...
In the above code, I need to know if I can convert a List to whatever type of list is passed in, e.g., List<Control>.
Is there a way to interrogate the generic for the contained type? I could get List<Control>, List<String>, List<Form> etc..
I could split the API to return lists in a separate method where the contained type is passed in, thus requiring the caller to use one method for lists and one for simple types. Either way they have to know what's coming back, but if there's a smooth way to do what I'm asking about, I'd rather keep the API simple.
Note: this is a solution to the lack of covariance because even though there is an implicit conversion operator defined on the contained type, a cast of List to T fails. So, in order to follow the solution listOfB.Cast<A>(); from here, I need to know to what to cast (what is A).
Thanks!
You can start with typeof(T) to get an instance of System.Type that represents T.
Once you have that, you can check Type.IsGenericType to see if it really is a generic and then call Type.GetGenericArguments() to see what generic arguments were used.
For example, if T was List<int> IsGenericType would be true and GetGenericArguments() would return an array containing one element: System.Int32
For example, here is a snippet of code I wrote to see if a given type (variable type) is some implementation if IEnumerable<T> where T is not known. It first has to see if it is a generic, then work out whether it has only one argument, determine said argument and see if it implements the interface, given that argument:
if (type.IsGenericType)
{
Type[] genericArguments = type.GetGenericArguments();
if (genericArguments.Length == 1)
{
Type proposedEnumerable = typeof(IEnumerable<>).MakeGenericType(genericArguments);
if (proposedEnumerable.IsAssignableFrom(type))
{
For reference, see:
http://msdn.microsoft.com/en-us/library/system.type.isgenerictype(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.type.getgenericarguments(v=vs.110).aspx
I have a large number of classes.
From this list I get a specified type
Type aType = Type.GetType(...);
Now I want to use this type in a linq statement like:
var aResult = from obj in scope.Extent<aType>() select obj;
This does not seem to be possible, as Extent does not accept Type.
Is there any way now (with .net 4.5) to call the statement?
All I want to do is to say use Type as class. Don't invoke the class, only get with linq all objects of this type from a scope.
You can't use an instance of Type as a generic type argument - not at compile time, anyway.
If you want objects of a specific type, you could do
var aResult = from obj in scope where obj.GetType() == aType select obj;
Note that this requires an exact type match, rather than any kind of "can be assigned to" relationship.
Also note that this will only get you a series of objects - again there's no compile-time way to cast things to an instance of Type.
Given a generic list of type List<T> how do I find type T?
I suppose if the list is populated I could take listInstance[0].GetType() but that seems a bit hackish.
Edit:
For context, I want to populate a DataTable with columns based on the Properties of an object. Where an object property is a generic list I want to add a column for each property of the object stored by the list. I'll flatten the data structure to fit into a DataRow later.
The reason I don't want to use the type of the first object in the list is because it's not guaranteed that every instance will have the list populated. Some will and some won't, but I'll still need all the columns ahead of time.
You could try
typeof(List<T>).GetGenericArguments()[0]
This works with an empty array, while your version does not.
UPDATE:
On an instance use
instance.GetType().GetGenericArguments()[0]
Why is that hackish?, is not hackish at all. That is why the GetType() method exits. To obtain the type of the object.
You can use
myList.GetType().GetGenericArguments()
This returns an array of all the types specified in the declaration of the object.
It is hackish because if the list isn't populated, you can't get an answer.
You'll need to reflect against the Type:
List<int> mylist = new List<int>();
Type listType = mylist.GetType();
Type genericType = listType.GetGenericArguments()[0];
Do it as you said. It is not hackish.
You can also call GetType() directly on your list and use it to look at type of its its T.
You could also do listInstance[0] is SomeTypeIExpectThisToBe if you are expecting a type and want to do something because of that
You should have access to the type parameter, so you can use typeof:
void ProcessList<T>( List<T> listInstance)
{
Type type = typeof(T);
}
This is a quick one. I have the following code:
foreach (var item in myRepeater.Items)
{
MyViewModelItem x = new MyViewModelItem();
MapToEntity(x, item);
myList.Add(report);
}
void MapToEntity(object entity, Control control);
I expected this code to compile with no problems. It didn't, however.
It resulted in a compile time error saying that the method "MapToEntity" has some invalid arguments. The compiler failed to infer the type of the RepeaterItem, it recognizes it as a plain System.Object.
Why is this happening? Am I missing something?
Ps: I fixed the code by deleting the var keyword and explicitly defining the type of the item "RepeaterItem".
RepeaterItemCollection does not implement IEnumerable<RepeaterItem> just plain IEnumerable. Thus, it's impossible for the compiler in infer the type.
First, your code sample shows that you are using a variable named "item" in the foreach statement and then declaring one of another type below it.
Second the reason you probably seeing it as type Object is that myRepeater.Items is probably a general collection and not a specifically typed one so it would return of type Object. You can specifically state of what type in the ForEach loop and it will return objects of that type if any exist.
A possible solution would be to do myRepeater.Items.OfType() and then you could use the var keyword.
As Anton said, the Items only implements IEnumerable which is why it cannot infer the type.
One thing that you may find useful though is the Cast method.
myRepeater.Items.Cast<RepeaterItem>()
Whilst your example is simple enough for this to not really be needed it may help for more complex examples where you need a typed enumerable.