简体   繁体   中英

Cannot cast from source type to destination type C#

I have the following function that should be able to return a generic value. Like so:

T ReturnValueMatchedType<T>(ObjectTypes t, ReturnValues v)
{
    if(t == ObjectTypes.int_type)
        return (T) Convert.ChangeType(v.IntValue, typeof(int));
    else if(t == ObjectTypes.float_type)
        return (T) Convert.ChangeType(v.FloatValue, typeof(float));
    else if(t == ObjectTypes.string_type)
        return (T) Convert.ChangeType(v.StringValue, typeof(string));
    else if(t == ObjectTypes.char_type)
        return (T) Convert.ChangeType(v.CharValue, typeof(string));
    else 
        return (T) Convert.ChangeType(null, typeof(System.Object));
}

I use this function in a math formula. Like so:

VarDetectorA.DetectedVariable.GetVariableValue().IntValue - ReturnValueMatchedType<int>(VarDetectorB.DetectedVariable.GetVariableType(), VarDetectorB.DetectedVariable.GetVariableValue());

Since i use a generic method i need to supply the type it should return at the beginning. (which i dont know at that time). Since my generic function wil find the correct type to return. So i just used a place holder like <int> But then when i run the function i get the following error:

Cannot cast from source type to destination type

I think it has to do with the fact that i call the method with the <int> . But i cant use System.Object since that is not valid in a math operation. How do i Make my function always return the correct type.

I know this may be a bit vague, but this is kinda my first time doing something with Generics in C#. So if something isnt clear pls let me know so i can clarify!

As you really dont know the type here, may be we can use the dynamic typing to achive this. Something like

dynamic ReturnValueMatchedType(ObjectTypes t, ReturnValues v)
        {
            if (t == ObjectTypes.int_type)
                return Convert.ChangeType(v.IntValue, typeof(int));
            else if (t == ObjectTypes.float_type)
                return Convert.ChangeType(v.FloatValue, typeof(float));
            else if (t == ObjectTypes.string_type)
                return Convert.ChangeType(v.StringValue, typeof(string));
            else if (t == ObjectTypes.char_type)
                return Convert.ChangeType(v.CharValue, typeof(string));
            else
                return Convert.ChangeType(null, typeof(System.Object));
        }

I'm not sure what ObjectTypes is, especially when it already exists in .Net as enum TypeCode .

What I suspect you want is:

using System;

public class Program
{
    public static void Main()
    {
        var rv = new ReturnValues
        {
            Boolean = true,
            Double = 20.1,
            String = "myString"
        };

        Console.WriteLine(ReturnValueMatchedType<bool>(rv));
        Console.WriteLine(ReturnValueMatchedType<Double>(rv));
        Console.WriteLine(ReturnValueMatchedType<string>(rv));
    }

    public class ReturnValues
    {
        public bool Boolean { get; set; }
        public Double Double { get; set; }
        public string String { get; set; }
    }

    public static T ReturnValueMatchedType<T>(ReturnValues v)
    {
      var typeCode = Type.GetTypeCode(typeof(T));

      switch( typeCode )
      {
        case TypeCode.Boolean:
              return (T)(object)v.Boolean;

        case TypeCode.Double:
              return (T)(object)v.Double;

        case TypeCode.String:
              return (T)(object)v.String;

        default:
            return default(T);          
      }
    }
}

DotNetFiddle Example

output

True

20.1

myString

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM