Typecasting based on a variable - c#

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.

Related

Cast object according to string's value in C#

Let's say I have:
string ValueToCastTo;
object TheThing;
If ValueToCastTo is set to "int", I want TheThing to be casted to an int.
If ValueToCastTo is set to "DateTime", I want TheThing to be casted to a DateTime.
I can't use if statements because the string could be set to anything.
Thanks.
You'll need:
Type.GetType(string)
plus a built-in list corresponding to C# keywords, since GetType expects System.Int32 not int.
Convert.ChangeType(object, Type)
Maybe the runtime will figure out the right conversion, but normally it won't. So also write a whole lot of TypeConverter implementations and then use
TypeDescriptor.GetConverter(Type) followed by either TypeConverter.ConvertFrom(object) or TypeConverter.ConvertTo(object, Type) depending on which type knows about the other one
and when you're done, the static type will still be object. But it'll be a handle to an instance of your new type. Whether that helps you depends on exactly what you want to do with it...
TypeOf() you can use to get the type and then do reflection.
"C# - Reflection objects are used for obtaining type information at runtime. The classes that give access to the metadata of a running program are in the System.Reflection namespace."
You can follow that path to get what you want.
Hope that helps!
Short answer: you can't.
A cast is something you have to write at compile time, to assign a variable of type X an object of type Y.
A cast imply that you know at compile time the type you want to assign to, so you can write something such
int x = (int) y;
string x = (string) y;
There are workarounds to this: use TypeOf() on your object, use reflection to detect at runtime type, properties and methods of the object, or use dynamic to avoid compile time checks.
But it actually depends on what you are trying to get from your code.

Access <AnonymousType> fields

I have an AnonymousType object that contacts two fields with their values. How can I access the value of these fields?
Ex:
SourceTypeObject { Source_Type_Id = 1, Source_Type_Name = "bibliography" }
I need to do something like : SourceTypeObject.Source_Type_Id
Is that possible?
EDIT:
Here's what I get if I tried to access the property directly:
Yes, this is the exact purpose of anonymous types. The only thing that might prevent you from doing so is if you passed the anonymous type around as a parameter with type "object". This would hide information about the anonymous type, and it would look like just any old object then.
The only recourse if this is the case is to use reflection, which is slow and awkward. Anonymous types are a meant to be a very "local" phenomenon, and if you find yourself wanting to use them elsewhere in the program, it's worth the time to promote it to a real type.
EDIT: In response to the image you posted, assuming the array is declared locally just outside of view, try to replace the object SourceTypeObject with var SourceTypeObject. This allows it to infer the anonymous type instead of being told that it's an object.

TypeConverter vs. Convert vs. TargetType.Parse

As far as I know, there are at least 3 ways to convert data types in .NET:
using System.ComponentModel.TypeConverter
var conv = System.ComponentModel.TypeDescriptor.GetConverter(typeof(int));
var i1 = (int)conv.ConvertFrom("123");
using System.Convert.ChangeType():
var i2 = (int) Convert.ChangeType("123", typeof (int));
using the Parse/TryParse methods of the destination type:
var i3 = int.Parse("123"); // or TryParse
Are there any guidelines or rules-of-thumb when to use which method to convert between the .NET base data types (especially from string to some other data type)?
I'm going to post here 6 years late, because I think this is a good question and I am not satisfied with the existing answers.
The static Parse/TryParse methods can be used only when you want to convert from string to the type that has those methods. (use TryParse when you expect that the conversion may fail).
The point of System.Convert is, as its documentation says, to convert from a base data type to another base data type. Note that with Convert you also have methods that take an Object and figure out by themselves how to convert it.
As to System.ComponentModel.TypeConverter, as the "typeconverter" stack overflow tag's documentation, they are used primarily to convert to and from string, when you want to provide a text representation of a class instance for use by designer serialization or for display in property grids
Convert
Convert class uses the IConvertible methods implemented in the target type.
Unfortunately, implementing IConvertible means writing lots of boilerplate code and Convert.ChangeType causes boxing if the target type is a struct.
TypeConverterAttribute
TypeDescriptor.GetConverter uses the TypeConverterAttribute and IMHO offers both a better API to convert a type and a more elegant way to make a type convertible. But it suffers the same performance issues with the Convert class, caused by the methods not being generic.
Parse/TryParse
Using T.Parse/T.TryParse methods is the de facto way of creating an object from a string since it doesn't involve unnecessary boxing. They also usually have overloads that provide greater control of how to parse the string.
TryParse methods allow you to handle cases where the string you want to parse is obtained from user input or another mean that doesn't guarantee a properly formatted string, without throwing exceptions.
So you should call the type's Parse/TryParse methods when you can and fallback to the other ways only when you don't know the target type in the compile time, i.e. when you only have a Type object that represents your target type.
You can also have look at my little library called ValueString that finds the most suitable parsing method of a type and uses it to parse the string.
According to my personal preference and coding standards I choose between the following:
Convert. I use this when I am absolutely sure that the values will be what I expect.
int i = Convert.ToInt32("123");
TryParse. I use this when I am handling user input. This also has the benefit to be able to use localized formatting when parsing.
int i = 0;
bool parsed = Int32.TryParse("123", out i);
There is also the possibility to use TryParseExact, where a certain pattern can be parsed. It can be useful in certain cases.
Just found out a case that TypeConvert.ConvertFrom(object) throws exception.
If you want to convert an Integer 0/1 to a Boolean. You will get exception using TypeConvert.ConvertFrom(1) or (0). In this case, Convert.ChangeType(1, System.Boolean) works.
As a general rule of thumb, you should be avoiding the Convert class altogether. There are reasons to use it (e.g, you do not know the source type), but if you already know your source type is a string then Parse (or, more correctly, TryParse) is always the right method to use.
As for type converters, they are more often than not used when a framework (such as WPF) uses reflection to determine the right sort of type converter.
You forgot another way of converting, that is the direct cast. Take this code for example
object i = 1;
int myInt = (int)i;
This is a bit of a contrived example, but I already know that i is an int, its just that its boxed into an object. In this case I do not need to convert i, I just need to directly cast it to the type which I know it already is.
I pretty much always use the int/double/etc.Parse() methods, when I'm certain it's a number. In any case of doubt, I us the .TryParse() methods, as an all-in-one solution including parsing and checking. I have this feeling that checking and parsing combined is slightly more performant than doing them separately.
TypeConverter is probably only useful when you don't really know the types at compile time.
Another late answer. I have an application where I was using some code that looks like this:
var finalValue = Convert.ChangeType(sourceValue, targetProperty.PropertyType);
sourceValue would be a string representation of what I wanted which normally would be a primitive under a wrapper class. This way would work with regular data types. Even with entire classes. However, one day I stupidly decided to change the datatype of a property that was a double to a nullable one double? guess what? boom!
invalid cast from string to nullable double
This is the perfect scenario where you should use the TypeConverter class as follows:
void Main()
{
var ss = new[] {"2.01", "3.99", ""};
var conv = TypeDescriptor.GetConverter(typeof(A).GetProperties().First().PropertyType);
Console.WriteLine(string.Join(",", ss.Select(s => conv.ConvertFrom(s))));
}
class A {
public double? b {get; set;}
}
//2.01,3.99,

How to know that a parameter is an array?

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)))

Anonymous Types

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.

Categories

Resources