I have to cast an object to an object, where i just have the typename as a string.
For example:
I have the type-string System.DateTime and the string 2012-09-17T10:19:23.5369243+02:00. Now I want to have an object of DateTime with the value of the string.
Is this possible?
The answer to your question can be found in all the other answers, waiting to be pieced together. :)
Get the Type from your Type String, like akhisp said:
Type dateTimeType = Type.GetType("System.DateTime");
Now, use a type converter to change the string to the DateTime:
object date = Convert.ChangeType("2012-09-17T10:19:23.5369243+02:00", dateTimeType);
Usually this kind of conversion is not exposed through a cast. There are many reasons for this (and it could be a nice topic for an another question).
Sometimes the string representation of an object is pretty "standard" for that object. For example a color may always be serialized as a comma separated RGB triplet.
Things become harder when the type you need to parse introduces locale-dependent representations: a date, for example. In this case framework designers decided to do not introduce an interface like IParseable and to do this kind of stuff using a 3rd object:TypeConverters, TypeDescriptors and conversion classes. It makes your code more complicated but it allows to manage very complex conversions delegating the work to another class, take a look to:
System.ComponentModel.TypeConverter on MSDN.
System.ComponentModel.TypeDescriptor on MSDN.
Understanding the TypeDescriptor: A Metadata Engine for Designtime Code
For primitive types you may not even need to use them: you can rely on IConvertible interface and System.Convert class.
You can't do it with a cast (thanks God, in my opinion) but you can write a generic Parse method that accepts a string and returns the type you need, something like:
T Parse<T>(string value)
For what I remember there is a nice open source type conversion library (Universal Type Converter). It manages a lot of conversions using everything it may find to convert a type to another (imagine, for example, how many different string representations you may use for a bool value). Even if you won't use it directly you should read the article to understand how this things works (and to take a look to source code to see how corner cases have been handled).
What I would do is use the Type.GetType(String) method to get the Type of the object.
Then I would do a call to Activator.CreateInstance(Type Object[]) to construct an instance of that object, assuming you know that there is a constructor that takes in a string.
Related
When I use automapper, I purposely don't map a number of properties that are identical. That's one of the main reasons for me to use automapper. Outside of that, I can build a projection or class converter myself with about the same amount of code and less reflection (i.e., more performant).
The only issue I have is that we occasionally have some type mismatches. Is it possible to use automapper's configuration validation to confirm that the types are interchangeable?
I know that for some types, like string to int, that can't be validated 100% because someone could use a string that isn't convertible to an integer. But some types like timespan to datetime are not convertible without an explicit map. I would like to call those out. The existing AssertConfigurationIsValid() method fails to satisfy my needs because of the strict combination of explicit mapping/ignoring needed for it to only ever complain about type mismatches instead.
This is not supported by the library. One possible solution is to write our own validation process that only checks the source and destination type with some variation of casts and try/catching Convert.ChangeType().
I am trying to get the name of a method on a generic interface. I would expect this to work as the type part would be a valid typeof:
//This does not compile
nameof(IGenericInterface<>.Method)
//This would compile
typeof(IGenericInterface<>)
I think this should be valid c#-6.0 or am I missing something or is there a better way to do this. I don't want to use a string for the Method name as if the method is renamed code would break without any build-time errors.
This is expected. According to the documentation, your expression is disallowed, because it refers to an unbound generic type:
Because the argument needs to be an expression syntactically, there are many things disallowed that are not useful to list. The following are worth mentioning that produce errors: predefined types (for example, int or void), nullable types (Point?), array types (Customer[,]), pointer types (Buffer*), qualified alias (A::B), and unbound generic types (Dictionary<,>), preprocessing symbols (DEBUG), and labels (loop:).
You can work around this limitation by supplying a generic parameter:
nameof(IGenericInterface<object>.Method)
Note: I think Microsoft should tweak nameof feature to allow references to methods of unbound generic types.
Just use a sample type in order to compile.
string name = nameof(IGenericInterface<int>.Method) // will be Method
The solutions presented with "sample types" will work, but sooner or later you will need to get the nameof a generic type which has type constraints, so nameof(MyGenericType<object>) won't work, because object does not abide by the constraints.
If you find yourself in this situation, it might seem that you have to declare a dummy little class real quick which abides by the constraints so that you can get its nameof, but having to do something as hacky as that is a clear indication that you are down the wrong rabbit hole.
Here is a better solution:
typeof(MyGenericType<>).Name
Interestingly enough, C# allows us to use <> in typeof but not in nameof. Go figure.
I'm building a HTTP-API wrapper for .NET, which has a bunch of methods to set data in an object, and then it serializes the data and sends it to my server. There are 6 datatypes allowed:
string
int
long
float
double
DateTime
My data attributes use generics:
SetAttribute<T>(string key, T value)
So there is only one generic method to set data. Since I cannot constrain the data types to the 6 mentioned, I use run-time checks and throw an exception when the wrong data type is used.
Now for my problem: I have two versions of SetAttribute, one that takes a single value (of type T) and one that takes multiple values (of type IEnumerable<T>). The problem is that when a programmer uses this wrapper and does not specify the type parameter, the runtime guesses which method to use, for instance:
SetAttribute("testkey","thing,anotherthing,athirdthing".Split(','))
This defaults to the single value method and T is String[] which of course makes my method cast an exception because String[] is not a valid type. If you specify:
SetAttribute<string>("testkey","thing,anotherThing,aThirdThing".Split(','))
The runtime chooses the correct method (multi-value) and no exception is cast because T is then string.
My question: how can I label my methods so that the type parameter is mandatory and must be explicitly defined? Or do I have to detect this at runtime and redirect to the multi-method myself?
Ok, this was originally a comment above since it doesn't necessarily answer your original question but suggests an alternate approach;
I would say using a public generic SetAttribute in this case isn't necessarily a good idea.
Since the types are so constrained, you should probably just write the overloads and move the errors from runtime to compile time. It would also allow you to take IEnumerable<string> etc. with another 6 overloads and eliminate the problem you're having entirely.
You can always implement SetAttribute with a private generic and just call that from each overload, that will remove some duplication.
It will also more or less eliminate the need for runtime checks, since the types are already constrained by the compiler.
Given a parameter type, the compiler finds a best match from your overloads. If you cast your string[] to an IEnumerable<string> you will probably find it works as expected because the best match is a method that has exactly those parameters. But you have no method that takes a string[], so given one as a parameter, the compiler makes the best guess it can.
I would have two separately named methods rather than overloads otherwise it is too easy to run into this problem. Or have 6 separate overloads, as #Joachim suggests.
I would suggest a better solution would be to test whether the value passed in is IEnumerable after it fails everything else and treat it as such if it is. (I imagine that you're handling IEnumerable as a seventh case already).
One solution would be to break your original method into 6 non-generic overloads, and add another generic overload for collections:
void SetAttribute(string key, int value);
void SetAttribute(string key, string value);
// etc
// abd this takes care of collections:
void SetAttribute<T>(string key, IEnumerable<T> value);
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 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.