无法从源类型转换为目标类型C#

时间:2019-01-04 22:16:37

标签: c# generics methods return-type

我有以下应该可以返回通用值的函数。像这样:

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));
}

我在数学公式中使用此函数。像这样:

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

由于我使用的是通用方法,因此我需要提供应在开始时返回的类型。 (当时我还不知道)。由于我的泛型函数会找到要返回的正确类型。所以我只使用了<int>之类的占位符,但是当我运行该函数时,出现以下错误:

  

无法从源类型转换为目标类型

我认为这与我用<int>调用方法有关。但是我不能使用System.Object,因为这在数学运算中无效。如何使函数始终返回正确的类型。

我知道这可能有点含糊,但这是我第一次在C#中使用Generics做一些事情。所以,如果有不清楚的地方,请告诉我,以便我澄清!

2 个答案:

答案 0 :(得分:0)

由于您真的不知道这里的类型,可能是我们可以使用动态类型来实现这一点。 像

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));
        }

答案 1 :(得分:0)

我不确定ObjectTypes是什么,尤其是当它在{.3}}中已经存在于.Net中时。

我怀疑你想要的是

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);          
      }
    }
}

enum TypeCode

输出

  

     

20.1

     

myString