Alex Dobrynin
Alex Dobrynin

Reputation: 66

How to cast object to type c#

I have few variables of type

Int16[], Double[]

i push them to a func like this

Int16[] variable = ...;
Func(variable);

or

Double[] variable = ...;
Func(variable);

///////////////////////////////
private void Func(Object input)
{
    var data = (input.GetType())input; ?????

    //some actions with data
}

In this case

var data = input.ToString();

data becomes string with content "System.Int16[]" or "System.Double[]"

How can i cast input object that my data becomes type of Int16[] or Double[] in func, i.e. data should be array of Int16[] or Double[] or any type I push in func that I could do for example this action:

for(int i = 0; i < data.length; ++i)
{
    data[i] = data[i] * 5;
}

Upvotes: 2

Views: 609

Answers (4)

Fᴀʀʜᴀɴ Aɴᴀᴍ
Fᴀʀʜᴀɴ Aɴᴀᴍ

Reputation: 6251

I think you want Type arguments like this:

private void Func<T>(T[] input)
    {
        var data = input; //Unnecessary but since you used it, so did I.
        // Now you can perform actions with data.
        // Call this function like this:
        // Func<Double>(variable) or Func<Int16>(variable) or any other type you want.
    }

Upvotes: 0

alexm
alexm

Reputation: 6882

How can i cast input object that my data becomes type of Int16[] or Double[] in func,

If operations with arrays are prevailing I would encapsulate common arithmetic operations in an interface to use it from generic functions.

interface IArithmeticOperation<T> 
{
    void Shift(T[] left, object value);
    void Scale(T[] left, object value);
}

private void MyFunction<T>(T[] data) 
{   
    var ops = GetOperations<T>();
    ops.Scale(data, 5);
}


IArithmeticOperations<T> GetOperations<T>()
{ 
    object result;

    switch(Type.GetTypeCode(typeof(T))
    {
       case TypeCode.Double:
         result = new DoubleArithmeticOperations();  
         break;
       case TypeCode.Int16:
         result = new Int16ArithmeticOperations();  
         break;

       defaut:            
           throw new InvalidOperationException("Unsupported type");
    }

    return (IArithmeticOperation<T>) result;
}

Usage:

var int16Data = new short[] {1, 2, 3, 4};
MyFunc(int16Data);

var doubleData = new double[] {1.0, 2.0, 3.0, 4.0};
MyFunc(doubleData);

Possible implementation:

class DoubleArithmeticOperation: IArithmeticOperation<Double>
{
    public void Shift(double[] left, object value) 
    { 
       double v = Convert.ToDouble(value);
       for(int i = 0; i < left.Length, ++i} {left[i] += v};
    }

    public void Scale(double[] left, object value) 
    {
        double v = Convert.ToDouble(value);
        for(int i = 0; i < left.Length, ++i} {left[i] *= v};
    }
}


class Int16ArithmeticOperation: IArithmeticOperation<Int16>
{
    public void Shift(short[] left, object value) 
    { 
        short v = Convert.ToInt16(value); 
        for(int i = 0; i < left.Length, ++i} {left[i] += v};
    }

    public void Scale(short[] left, object value) 
    {
        short v = Convert.ToInt16(value); 
        for(int i = 0; i < left.Length, ++i} {left[i] *= v};
    }
}

Upvotes: 0

Kevin Smith
Kevin Smith

Reputation: 14466

You can you Convert.ChangeType see below:

var valueType = typeof (TValue);
valueType = Nullable.GetUnderlyingType(valueType) ??  valueType;

var value = (TValue) Convert.ChangeType(environmentValue, valueType);

Upvotes: 1

Ron Beyer
Ron Beyer

Reputation: 11273

You have a couple options here, first you could go with a generic function:

private void MyFunction<T>(T[] values)
{
    for (int i = 0; i < values.Length; i++)
    {
        //Here is where the issue is, you can't constrain T to a value type that
        //defines mathematical operators, so the best you can do is dynamic:
        values[i] = (dynamic)values[i] * 5;
    }
}

Or you could do something like this:

private void MyFunction(object values)
{
    //Assume that object is an array, and go from there
    for (int i = 0; i < ((dynamic)values).Length; i++)
    {
        ((dynamic)values)[i] = ((dynamic)values)[i] * 5;
    }
}

Which I think is a lot dirtier. Either way, you should be doing some sort of type checking at the tops of these functions to verify that the argument passed in is of a numeric array type before assuming it is and running through the code.

The line that you posted:

var data = (input.GetType())input;

Obviously doesn't work because GetType() returns a System.Type, it doesn't, at compile time, replace itself with the name of the type, so its not a valid cast.

Upvotes: 2

Related Questions