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.
Related
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,
In the latest version of C#, is it possible to convert a dynamic type to a strong type, if you know the type in advance?
I'm using reflection to call a method on an object, which returns to a var:
var returnVal = context.GetType().InvokeMember(MethodName, BindingFlags.InvokeMethod, null, context, lParams.ToArray());
I can easily get the type being returned to returnVal. Is it possible to cast\convert thins to a more strongly typed version?
EDIT FOR CLARITY:
In this situation, I know the type being returned but only by string. To get the type, I have to do:
diAssemblies[k].GetType(diAssemblies[k].GetName().Name + "." + returnType)
Where returnType is the name of type being returned.
Ideally, I'd like to be able to get the result of the method invocation in to a strongly typed field.
CONTEXT
I'm loading assemblies containing .edmx files from a directory, then invoking methos on those contexts. At run time, the loader won't know what assemblies it's going to be loading. However, the person using the loader will be aware of the assemblies, methods and types.
This is to create a generic wrapper around database calls through entity framework (with stored procedures), that will be reused elsewhere.
If you don't know the Type statically, how could you use a statically typed reference? What you can do is have the returned type implement an interface you do know about statically, then cast to that interface.
So, if MyStrongType implements IMyStrongBehavior, you can cast the return value to IMyStrongBehavior and use that statically. The underlying value is already strongly typed, regardless of whether you cast it.
Alternately, you can store the return value in a dynamic variable (which will allow you to invoke known methods without an actual statically-typed interface.) The disadvantage here is that you don't get any Intellisense and any mistakes you make won't show up until runtime.
No, you can't get the advantages of a concrete type such as compile time checking and intellisense. This is because you are only actually working out what the type is at run time. It is late bound, which means that it's a job for dynamic and the DLR. You can cast it to an object that you know the actual object will inherit from (e.g. object), but you can't cast to the actual type. You might want to look into generics as an alternative if you had for example:
public T GetReturnVal<T>()
{
return (T)context.GetType().InvokeMember(MethodName, BindingFlags.InvokeMethod, null, context, lParams.ToArray());
}
You would at least be returning a concrete type to callers of type T. But this type has to be set at compile time, i.e. known in advance.
I recomend you read An Introduction to C# Generics as it does exactly what, from the context you've added, you need to do.
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.
int number = 5;
Type dynamicType = number.GetType(); // dynamic type is "int"
dynamicType x = (number as dynamicType);
How would you expect the compiler to treat the variable x later in the code? It wouldn't know anything about it... so it couldn't resolve any method calls etc.
Basically what you're after is dynamic typing which is supported in C# 4 with the "dynamic" pseudo-type:
int number = 5;
dynamic d = number;
// Calls to d are resolved at execution time, so this compiles:
d.ThisWillThrowAtExecutionTime();
Type is an object that represents information about a type. It's not a designator for a variable saying it is of that type.
SomeObject myObject = new SomeObject();
Type t = myObject.GetType();
SomeObject myOtherObject = (SomeObject)Activator.CreateInstance(t);
The ability to do this goes all the way back to .Net v1.0. No need for fancy dynamic typing or anything like that.
Constructing objects with more complex constructors takes a bit more work, but it's the same idea.
You can, just not directly. You can use reflection. Basically you get the fully qualified name of the type (from the Type object) and then call CreateInstance method from an assembly object that contains that type. It should be quite simple to get the assembly reference of the current instance...
I think the Assembly.GetExecutingAssembly() method will do it.
I've written a little about this quite some time ago in a post at: http://frater.wordpress.com/2007/06/24/instantiating-classes-through-reflection-using-c-dynamic-object-creation/
That might help you out some more, though the focus was also on compiling of c# code from within a c# program, to allow for the use of C# as a scripting language, so some of the details might not be completely relevant.
Hope that helps!
Because it wouldn't make any sense.
What would you do next?
The purpose of a cast is to assign the casted object to a variable of the type that you casted it to. In this case, you wouldn't be able to do that, since a field must have a static type at compile time.
What are you trying to do?
dynamicType is an object of type "Type" that holds the Type meta-data information of type "int" hence dynamicType is and instance or object and not a qualified type so you cannot perform instantiation on that.
So, AFAIK you can't use the Type to instantiate 'basic' data types such as int.
You could use it to create objects though:
Object x=Activator.CreateInstance(dynamicType)
The issue is, if you want to call methods or access fields on a dynamic type, you have to use reflection. See the Type class documentation for instructions.
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.