I'm working with reflection and when I get the parameters' list of a method, I need to examine all of them, when I find any one which its type is an array I need to avoid it, I mean array of any kind, so I used the following which doesn't work:
(!(parameter.GetType().Equals(Array)))
The error was that I'm using a type as a variable!! What can I do to accomplish that, any suggestions??
Try
(!(parameter.GetType().IsArray))
NOTE - from MSDN:
The IsArray property returns false for
the Array class.
To check for an array, use code such
as
typeof(Array).IsAssignableFrom(type).
If the current Type represents a
generic type, or a type parameter in
the definition of a generic type or
generic method, this property always
returns false.
Meaning that if you have simple array declarations like int[], string[], etc etc, the IsArray is fine, but if not then you will have to use IsAssignableFrom().
You are using a type ('Array') as a variable. There is a difference between a variable of type 'System.Type' (represents a type) and an actual type. To convert a type to a System.Type you use typeof(type).
Now, you don't want all things that are type Array, but rather those objects that could be assigned to an object that is type Array (i.e. Array or its descendants). It's a little backwards but the way to do that is to see if the System.Type for Array is assignable from the System.Type for your variable's type.
So, as a general pattern you want to try something like this:
( !(typeof(Array).IsAssignableFrom(parameter.GetType())) )
However, as another answer shows, System.Type has an IsArray property which skips this for you, so long as you are dealing with an actual array (int[], bool[] etc.) and not a custom Array descendant (e.g. something like CustomArrayClass : Array).
As I'm using parameters, I shouldn't use "GetType", like this:
( !(typeof(Array).IsAssignableFrom(parameter.GetType())) )
This only works for assigned objects, with parameters this will return the type parameterInfo.
For parameters, "ParameterType" should be used and answer will look like this:
( !(typeof(Array).IsAssignableFrom(parameter.ParameterType)))
Related
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 an object called SampleObject that holds an array of strings called StringArray. In order for me to access the first element in that array I need to write:
((string[])(SampleObject))[0]
However if I were to not know the type of the array how would I be able to approach this?
((SampleObject.GetType())(SampleObject))[0];
I tried something like this but it expects a method name.
Thanks.
You can use Array.GetValue - all array types are derived from Array, whatever the element type is. You may need to think carefully about rectangular arrays though, and arrays with a non-zero lower bound.
While Jon's answer is correct, you can abuse array co-variance, provided you have a normal (one dimensional, starting at 0) array of reference type.
return ((object[])SampleObject)[3];
Return the 3rd element in the array. You can also cast it to a non-generic IList if it not only will change the element type, but possibly the container itself.
If they are going to be based on c# object class, you can use GetType() - this will return a System.Type (see http://msdn.microsoft.com/en-us/library/system.object.gettype.aspx). Otherwise you could base them off your own base object that has a type define for all possible values.
Another approach would be to use Reflection to determine the type and to manipulate the data. While this is applicable on all types of objects (not only arrays), for the scenario you described I would go with the solution of Jon Skeet.
I have an array of Type objects corresponding to int, bool, string, float, int? ...
How do I write a function that takes in the above array and returns strongly typed default values for each type in the array?
To get a default value from a Type, simply invoke Activator.CreateInstance
object obj = Activator.CreateInstance(theType);
As for the bit about getting a strong type, the problem is that when you use reflection in this manner, it deals in objects. To get a strong type, you would need to know it at compile time, which kind of defeats your purpose. When you're doing these things at runtime, you're left with object or dynamic (which is just object behind the scenes).
Beyond that, if you're talking about running the array through a method and returning default values for each type, you're going to be talking about returning an IEnumerable<object> or object[] array, as the type of each item would obviously differ.
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.
How would I go about the following... I have a control that can be bound to different data types... String, Int, Int32, DateTime, etc... but generically the result is stored into a generic "object" data type. So, I use another field to identify the EXPECTED type such as..
String BoundDataType = "System.String" // or System.Int32 or date/time, etc.
object ChosenValue;
For comparison purposes, I would now have to enforce typecasting of expected format, such as
(DataBoundType)ChosenValue == (DataBoundType)TestAgainstThisValue;
I know i could put inside a switch, or overloaded functions with different Signatures per data type, but looking for a more generic way to handle directly.
Thanks
You don't actually need a separate BoundDataType property - object.GetType() will suffice.
As for comparison, most standard types implement IComparable interface, which can be used to test for equality.
Use the System.ComponentModel.TypeConverter-Class
Try
TestAgainstThisValue.GetType()
to get the type of the variable
you can use object.GetType() to get the type of the variable.
Then you can use Convert.ChangeType(object,type) to make the conversion.
object conv = Convert.ChangeType(ChosenValue,ChosenValue.GetType());
this should work.