I have a list collection of following type
CoordinateCollection pointCoordinates = new CoordinateCollection();
it adds up list of type vector.
I want to remove duplicate entries from the list
I am trying like this
pointCoordinates = pointCoordinates.Distinct();
it gives me an error
cannot implicitly convert type 'system.collections.generic.ienumerable<SharpKML.Base.Vector> to SharpKML.Dom.CoordinateCollection
Please help me in solving this. I want unique set of records
Since CoordinateCollection implements ICollection<Vector> and Vector overrides Equals + GethashCode you can use Distinct. But you need to use the constructor of CoordinateCollection to create a new:
pointCoordinates = new CoordinateCollection(pointCoordinates.Distinct());
Note that i'm not familiar with SharpKML, i have looked at it's source code.
As the message states, you can't implicitly assign an object of type system.collections.generic.ienumerable<SharpKML.Base.Vector> to an object of type SharpKML.Dom.CoordinateCollection. I would suggest using one of their type conversion methods (documented here).
Distinct is going to return an IEnumerable<SharpKML.Base.Vector>. You can't assign that type to your CoordinateCollection instance because even though is is an IEnumerable<SharpKML.Base.Vector> it may not also be an instance of CoordinateCollection.
If you need an instance of CoordinateCollection create/use a constructor that will take an IEnumerable<SharpKML.Base.Vector> as input otherwise if an IEnumerable<SharpKML.Base.Vector> will do then declare your variable as such.
Related
Imagine following "path" :
MyObject.MyFirstList[0].MySecondList[0].MyProperty = "Hello"
MyProperty is of type String.
None of the types is known at compiletime, only runtime via reflection of assembly.
I have everything, but i can not set the second list on the first with SetValue. I always get either null-ref exceptions or "target type does not match".
What I have tried so far:
iteration 1:
var constructedList = Activator.CreateInstance(constructedListType);
target.GetType().GetProperty(propertyToAdd).SetValue(target, constructedList)
Iteration 2:
Same way, works as well. So now we have MyObject.MyFirstList[0].MySecondList[]
Iteration 3: TODO: Create instance of first object of MySecondList and set its MyProperty-property to the created property:
var target = Activator.CreateInstance(typeOfItem);
target.GetType().GetProperty(propertyToAdd)?.SetValue(target, null);
So to summarize the question:
This works:
someInstance.GetType().GetProperty(someProperty).SetValue(someInstance, objToSet);
Why does something like this not work? Or does it - if yes, how?
someInstance.GetType().GetProperty(someList.listInsideSomeList.finalProperty).SetValue(...);
In short, reflection provides you with means to get information on a type. It cannot be used to reference the property of another type (as shown in your last example).
You are on the right track, but you need to go from right to left in your path. So taken you have some nested properties. You first create the nested object, such as:
var objNested = Activator.CreateInstance(objNestedType);
objNestedType.GetProperty(nestedPropertyName).SetValue(objNested, value);
and then you add your newly created object to its 'parent':
var objBase = Activator.CreateInstance(objBaseType);
objBaseType.GetProperty(basePropertyName).SetValue(objBase, objNested);
Arrays are bit different. Reflection expects you to write down the final value when using propertyinfo.SetValue, in case of an array this is the entire array value. In order to do this you can use Array.CreateInstance(typeof(arrayType), arrayLength) to create a new array and use the 'SetValue(object, index)' method to set its contents.
if class type list is there named
Collection<PurchaseOrderDetail> poDetails = new Collection<PurchaseOrderDetail>();
and another list with same type is there named _poH.PODetail
why _poH.PODetail = poDetails.ToList(); generates an error
Cannot implicitly convert type 'System.Collections.Generic.List'
to 'System.Collections.ObjectModel.Collection'
what is the solution for this, any explanation please.
All the reason behind the question is
_poH.PODetail = poDetails;
made poDetails.RemoveAt(Convert.ToInt32(e.RowIndex)); updates as well so I was searching for some thing like _poH.PODetail = poDetails.ToCollection();
According to the error message, _poH.PODetail is of type Collection, so assigning a list to it doesn’t work. But since poDetails is a collection itself, you can just assign it directly:
poH.PODetail = poDetails;
So you don’t actually need to call ToList() on it to convert it to a list.
There is no ToCollection method you could call on enumerables, but you could use the Collection constructor that takes a list to make it wrap that list and create a readonly collection:
new Collection(poDetails.ToList());
The short answer is simply that the ToList<T> extension returns an instance of List<T> class which, although similar, is not the same type as Collection<T>.
Basically this doesn't work for the same reasons you cannot set a string value to an integer variable.
One thing you can do though, is initializing the content of a new collection instance with an IList<T> instance. Therefore, the following should give you exactly what you want:
_poH.PODetail = new Collection(poDetails.ToList());
Also, as poke suggested, you might also want to assign the PODetail property with the poDetails variable itself.
_poH.PODetail = poDetails;
However, you must remember that Collection<T> is a reference type. This means that the objects in your collection won't be "copied" inside _poH.PODetail; instead, both poDetails and _poH.PODetail will be pointing to the exact same collection. Any changes done to one collection will automatically be reflected on the other.
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);
}
I am trying to call a class method dynamically depending on a condition. This is how I am doing it
I have three classes implement a single interface
interface IReadFile
{
string DoStuff();
}
The three classes A,B,C implement the interface above.
I am trying to add them to a hashtable with the code below
_HashT.Add("a", new classA());
_HashT.Add("b", new classB());
_HashT.Add("c", new classC());
This compiles fine, but gives a runtime error.{Object reference not set to an instance of an object.}
I was planning to return the correct class to the interface type depending on a parameter that matches the key value. say if I send in a. ClassA is returned to the interface type and the method is called.
IReadFile Obj = (IReadFile )_HashT["a"].GetType();
obj.DoStuff();
How do I correct the part above where the objects need to be added to the hashtable? Or do I need to use a different approach? All the classes are in the same assembly and namespace.
Thanks for your time.
As a guess, you have not instantiated your _HashT object.
You need somewhere in your code (declaration or constructor probably) to instantiate it:
HashTable _HashT = new HashTable();
If you do not do this, _HashT will be null and an attempt to add to it will fail with a NullReferenceException as you have been getting.
It appears you are seeing a NullReferenceException. Based on the limited code you provided I would say it is likely that the _HashT variable is not assigned. It could be possible that the exception is being generated from one of your class constructors as well.
If you use Dictionary<> you can use the following code to add and extract objects from the hashtable.
var hashtable = new Dictionary<IReadFile>();
hashtable.Add("a", new ClassA());
hashtable.Add("b", new ClassB());
hashtable.Add("c", new ClassC());
IReadFile obj = hashtable["a"];
obj.DoStuff();
Following your approach, you do not need to call GetType() on the value you pull out of _HashT. The value should already be an object of type IReadFile.
Why are you calling GetType? The IReadFile object is the thing you are putting in the hash. Casting a Type object into a IReadFile is not going to cast correctly.
I have a Dictionary(TKey, TValue) like
Dictionary<int, ArrayList> Deduction_Employees =
new Dictionary<int, ArrayList>();
and later I add to that array list an anonymous type like this
var day_and_type = new {
TheDay = myDay,
EntranceOrExit = isEntranceDelay
};
Deduction_Employees[Employee_ID].Add(day_and_type);
Now how can I unbox that var and access those properties ??
First, you aren't unboxing the type. Anonymous types are reference types, not structures.
Even though you can technically create instances of the same type outside of the method they were declared in (as per section 7.5.10.6 of the C# 3.0 Language Specification, which states:
Within the same program, two anonymous
object initializers that specify a
sequence of properties of the same
names and compile-time types in the
same order will produce instances of
the same anonymous type.
) you have no way of getting the name of the type, which you need in order to perform the cast from Object back to the type you created. You would have to resort to a cast-by-example solution which is inherently flawed.
Cast-by-example is flawed because from a design standpoint, every single place you want to access the type outside the function it is declared (and still inside the same module), you have to effectively declare the type all over again.
It's a duplication of effort that leads to sloppy design and implementation.
If you are using .NET 4.0, then you could place the object instance in a dynamic variable. However, the major drawback is the lack of compile-time verification of member access. You could easily misspell the name of the member, and then you have a run-time error instead of a compile-time error.
Ultimately, if you find the need to use an anonymous type outside the method it is declared in, then the only good solution is to create a concrete type and substitute the anonymous type for the concrete type.
There are several ways.
Since the comments seems to indicate that I suggest you do this, let me make it clear: You should be creating a named type for your object since you intend to pass it around.
First, you can use Reflection, which another answer here has already pointed out.
Another way, which tricks .NET into giving you the right type is known as "cast by example", and it goes something like this: You need to pass your object through a generic method call, which will return the object as the right type, by inferring the right type to return.
For instance, try this:
private static T CastByExample<T>(T example, object value)
{
return (T)value;
}
and to use it:
var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);
for the two ?? spots, you just need to pass something fitting the data type for those properties, the values will not be used.
This exploits the fact that multiple anonymous types containing the exact same properties, of the same type, in the same order, in the same assembly, will map to the same single type.
However, by this time you should be creating a named type instead.
An anonymous type has method scope. To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. However, this defeats the strong typing of the anonymous type. If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.
Source: http://msdn.microsoft.com/en-us/library/bb397696.aspx
No you can't. You can only access the properties by using reflection. The compiler has no way of knowing what the type was, and since it's an anonymous type, you can't cast it either.
If you are using .NET 1.x - 3.x, you must use reflection.
If you use .NET 4.0, you could use a dynamic type and call the expected properties.
In neither case do you need to unbox; that's for value types. Anonymous types are always reference types.