Casting a Variable Using a Type Variable

Casting a variable using a Type variable

Here is an example of a cast and a convert:

using System;

public T CastObject<T>(object input) {
return (T) input;
}

public T ConvertObject<T>(object input) {
return (T) Convert.ChangeType(input, typeof(T));
}

Edit:

Some people in the comments say that this answer doesn't answer the question. But the line (T) Convert.ChangeType(input, typeof(T)) provides the solution. The Convert.ChangeType method tries to convert any Object to the Type provided as the second argument.

For example:

Type intType = typeof(Int32);
object value1 = 1000.1;

// Variable value2 is now an int with a value of 1000, the compiler
// knows the exact type, it is safe to use and you will have autocomplete
int value2 = Convert.ChangeType(value1, intType);

// Variable value3 is now an int with a value of 1000, the compiler
// doesn't know the exact type so it will allow you to call any
// property or method on it, but will crash if it doesn't exist
dynamic value3 = Convert.ChangeType(value1, intType);

I've written the answer with generics, because I think it is a very likely sign of code smell when you want to cast a something to a something else without handling an actual type. With proper interfaces that shouldn't be necessary 99.9% of the times. There are perhaps a few edge cases when it comes to reflection that it might make sense, but I would recommend to avoid those cases.

Edit 2:

Few extra tips:

  • Try to keep your code as type-safe as possible. If the compiler doesn't know the type, then it can't check if your code is correct and things like autocomplete won't work. Simply said: if you can't predict the type(s) at compile time, then how would the compiler be able to?
  • If the classes that you are working with implement a common interface, you can cast the value to that interface. Otherwise consider creating your own interface and have the classes implement that interface.
  • If you are working with external libraries that you are dynamically importing, then also check for a common interface. Otherwise consider creating small wrapper classes that implement the interface.
  • If you want to make calls on the object, but don't care about the type, then store the value in an object or dynamic variable.
  • Generics can be a great way to create reusable code that applies to a lot of different types, without having to know the exact types involved.
  • If you are stuck then consider a different approach or code refactor. Does your code really have to be that dynamic? Does it have to account for any type there is?

cast with a Type variable

It is not possible to use a Type value to determine the type of an expression. (Generics type parameters are different than values as they are codified into the type-system.)

The value of the variable is from the run-time code execution, while the expression type is a compile-time construct. Needless to say, the compilation occurs before the code ever runs so using a variable for a cast is impossible.

Reflection (albiet unwieldy) or dynamic (which is basically easier-to-use-reflection) allow invoking arbitrary methods or accessing properties/fields against a generic object-typed expression - this is occasionally refered to as "late binding". However, the type of the expression upon which operations is invoked is still object.

Interfaces can be used to unify disparate class implementations for proper static typing. The newly created object can then cast to the applicable interface(s) are required. Just like with other expressions, the type is a compile-time construct (and as such the interface must be directly specified), but the code is now free from a particular class.

If creating a system such that these "dynamic classes" are to be used directly in statically typed (C#) code, and the interfaces can be guaranteed or are constrained to a small set, then using interfaces is likely the cleanest approach: e.g. var myAction = (IMyAction)obj. Otherwise, fall back to dynamic access - direct or behind a facade.

cast object with a Type variable

newObjectType is an instance of the Type class (containing metadata about the type) not the type itself.

This should work

var newObject = givenObject as MyClass;

OR

var newObject = (MyClass) givenObject;

Casting to an instance of a type really does not make sense since compile time has to know what the variable type should be while instance of a type is a runtime concept.

The only way var can work is that the type of the variable is known at compile-time.


UPDATE

Casting generally is a compile-time concept, i.e. you have to know the type at compile-time.

Type Conversion is a runtime concept.


UPDATE 2

If you need to make a call using a variable of the type and you do not know the type at compile time, you can use reflection: use Invoke method of the MethodInfo on the type instance.

object myString = "Ali";
Type type = myString.GetType();
MethodInfo methodInfo = type.GetMethods().Where(m=>m.Name == "ToUpper").First();
object invoked = methodInfo.Invoke(myString, null);
Console.WriteLine(invoked);
Console.ReadLine();

Is possible to cast a variable to a type stored in another variable?

No, you cannot. C# does not implement duck typing.

You must implement an interface and cast to it.

(However there are attempts to do it. Look at Duck Typing Project for an example.)

How can I cast an object using a known Type object?

If I understand you correctly, you could use the Convert.ChangeType method:

var anotherObject = Convert.ChangeType(anObjectVarThatIsReallyMyObjectClass, myKnownType);

You won't get any kind of compile-time checking when using a dynamic type like this though. Please refer to the following blog post for more information about this.

Generic type parameters and dynamic types in C#: https://blog.magnusmontin.net/2014/10/31/generic-type-parameters-and-dynamic-types-in-csharp/

Cast a variable based on the data type of another variable


// Cast will attempt to force cast something (n) into the type of
// something else (ref)
const cast = (n, ref) => {
switch(typeof(ref)) // All major types and how to convert them
{
case "boolean": return Boolean(n);
case "number": return Number(n);
case "bigint": return BigInt(n);
case "string": return String(n);
case "symbol": return Symbol(n);
case "undefined": return undefined;
default: return n; // If none of the above is the type, we return n
}
}

// Example: 2 is an int, and the reference is a string, so we cast an int
// to a string, this could be done with various types more complexly
let a = 2
let b = "hello"

a = cast(a, b)
console.log(a, typeof(a)) // 2, string

Casting to a type held in a variable

Swift (currently) requires the Type assignment at compile time. You can do some things like this, but you will need to write a converter for each type combination you want to use, e.g:

func convertType(from item: Int) -> Float {
return Float(item)
}

var item: Float = convertType(from: 1)

I would caution going down this road and try and get used to Swift's way of doing things. If you absolutely need it you should be able to use some generic functions with a protocol like FloatConvertable to handle this more simply.

Type casting with type in variable

No. The type cast is a compile time thing. It lets the compiler know what methods are available and how to do the linking.

You can use Mirror to gather information about your object at runtime, but it looks like invoking methods dynamically can still only be done on classes derived from NSObject.



Related Topics



Leave a reply



Submit