C# 如何隔离双精度项和字符串项,获取无效的强制转换错误

C# 如何隔离双精度项和字符串项,获取无效的强制转换错误,c#,double,boxing,C#,Double,Boxing,我有一本字典,它的对象有字符串和双值。现在我想在下面的代码中分离这两种值类型。当前我得到无效的强制转换错误。如何做到这一点 namespace ConsoleApp26 { public class Sample { public string SampleName; public Dictionary<string, object> SampleValues; } public class SampleDivideBetweenDoubleAndStringVal

我有一本字典,它的对象有字符串和双值。现在我想在下面的代码中分离这两种值类型。当前我得到无效的强制转换错误。如何做到这一点

namespace ConsoleApp26
{
public class Sample
{
    public string SampleName;
    public Dictionary<string, object> SampleValues;
}

public class SampleDivideBetweenDoubleAndStringValue
{
    public string Name { get; set; }
    public double DoubleValue { get; set; }
    public string StringValue { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var samples = new Sample
            {
                SampleName = "test",
                SampleValues = new Dictionary<string, object> { 
                    { "t1",  45.08 }, 
                    { "t2", "A String Value" }, 
                    { "t3",  83 } 
                }
            };

            var tuple = GetTuple(samples);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        Console.ReadKey();
    }

    private static Tuple<IEnumerable<SampleDivideBetweenDoubleAndStringValue>, IEnumerable<SampleDivideBetweenDoubleAndStringValue>> GetTuple(Sample samples)
    {
        var doubles = (from s in samples.SampleValues
                       select new SampleDivideBetweenDoubleAndStringValue
                       {
                           Name = samples.SampleName,
                           DoubleValue = (double)s.Value
                       });

        var strings = (from s in samples.SampleValues
                       select new SampleDivideBetweenDoubleAndStringValue
                       {
                           Name = samples.SampleName,
                           StringValue = (string)s.Value
                       });

        return new Tuple<
          IEnumerable<SampleDivideBetweenDoubleAndStringValue>, 
          IEnumerable<SampleDivideBetweenDoubleAndStringValue>>(doubles, strings);
    }
}
}

您需要字符串的键:

private static Tuple<IEnumerable<SampleDivideBetweenDoubleAndStringValue>, IEnumerable<SampleDivideBetweenDoubleAndStringValue>> GetTuple(Sample samples)
{
    var doubles = (from s in samples.SampleValues
                   select new SampleDivideBetweenDoubleAndStringValue
                   {
                       Name = samples.SampleName,
                       DoubleValue = (double)s.Value
                   });

    var strings = (from s in samples.SampleValues
                   select new SampleDivideBetweenDoubleAndStringValue
                   {
                       Name = samples.SampleName,
                       StringValue = (string)s.Key
                   });

    return new Tuple<IEnumerable<SampleDivideBetweenDoubleAndStringValue>, IEnumerable<SampleDivideBetweenDoubleAndStringValue>>(doubles, strings);
}
但你根本不需要强制执行这些值。在字典中,键是字符串,值是双精度的,不需要强制转换

编辑
我看不出来。瓦西里是对的。也许我应该删除我的答案,但在我阅读完整的问题之前,我会先教自己不要回答。

你想要字符串的键:

private static Tuple<IEnumerable<SampleDivideBetweenDoubleAndStringValue>, IEnumerable<SampleDivideBetweenDoubleAndStringValue>> GetTuple(Sample samples)
{
    var doubles = (from s in samples.SampleValues
                   select new SampleDivideBetweenDoubleAndStringValue
                   {
                       Name = samples.SampleName,
                       DoubleValue = (double)s.Value
                   });

    var strings = (from s in samples.SampleValues
                   select new SampleDivideBetweenDoubleAndStringValue
                   {
                       Name = samples.SampleName,
                       StringValue = (string)s.Key
                   });

    return new Tuple<IEnumerable<SampleDivideBetweenDoubleAndStringValue>, IEnumerable<SampleDivideBetweenDoubleAndStringValue>>(doubles, strings);
}
但你根本不需要强制执行这些值。在字典中,键是字符串,值是双精度的,不需要强制转换

编辑 我看不出来。瓦西里是对的。也许我应该删除我的答案,但在我阅读完整问题之前,我会先教自己不要回答。

您可以使用方法按类型筛选值,就像我使用的lambda语法一样

私有静态元组示例 { var doubles=samples.SampleValues.Wheres=>s.Value是double.Selects=>new sampledividebetween doubleandstringvalue { Name=samples.SampleName, DoubleValue=doubles.Value }; var strings=samples.SampleValues.Wheres=>s.Value为string.Selects=>new sampledividebetween-oubleandstringvalue { Name=samples.SampleName,StringValue=string s.Value }; 返回新的tupledouble、string; } 对于示例中的查询语法,只需使用

var doubles=来自samples.SampleValues中的s 其中s.值为双精度 选择new SampleDividetween DubleandStringValue { Name=samples.SampleName, DoubleValue=doubles.Value }; var strings=来自samples.SampleValues中的s 其中s.Value是字符串 选择new SampleDividetween DubleandStringValue { Name=samples.SampleName, StringValue=strings.Value }; 由于Linq使用延迟执行,因此只有在迭代IEnumerable之后,才会显示示例中的无效强制转换异常。还有一个不清楚的地方是83值,因为它是一个整数,您可以使用方法按类型筛选值,就像我使用的lambda语法一样

私有静态元组示例 { var doubles=samples.SampleValues.Wheres=>s.Value是double.Selects=>new sampledividebetween doubleandstringvalue { Name=samples.SampleName, DoubleValue=doubles.Value }; var strings=samples.SampleValues.Wheres=>s.Value为string.Selects=>new sampledividebetween-oubleandstringvalue { Name=samples.SampleName,StringValue=string s.Value }; 返回新的tupledouble、string; } 对于示例中的查询语法,只需使用

var doubles=来自samples.SampleValues中的s 其中s.值为双精度 选择new SampleDividetween DubleandStringValue { Name=samples.SampleName, DoubleValue=doubles.Value }; var strings=来自samples.SampleValues中的s 其中s.Value是字符串 选择new SampleDividetween DubleandStringValue { Name=samples.SampleName, StringValue=strings.Value };
由于Linq使用延迟执行,因此只有在迭代IEnumerable之后,才会显示示例中的无效强制转换异常。还有一个值为83的不清楚点,因为它是一个整数

您可以在投射之前检查对象的类型:

var doubles = (from s in samples.SampleValues
               where s.Value is double
               select new SampleDivideBetweenDoubleAndStringValue
               {
                   Name = samples.SampleName,
                   DoubleValue = (double)s.Value
               });
// same for `string`
或者,您可以使用:


您可以在强制转换之前检查对象的类型:

var doubles = (from s in samples.SampleValues
               where s.Value is double
               select new SampleDivideBetweenDoubleAndStringValue
               {
                   Name = samples.SampleName,
                   DoubleValue = (double)s.Value
               });
// same for `string`
或者,您可以使用:


数据结构的主要问题是,您不仅有string和double,还有int:

请注意,转换是可以的:

因此,您可以尝试筛选出字符串项,然后将所有剩余的double和int值转换为double;就你而言:

  var doubles = samples
    .SampleValues       
    .Where(pair => (pair.Value != null) && !(pair.Value is string)) // not string value
    .Select(pair => new {
       Name  = samples.Name,
       Value = Convert.ToDouble(pair.Value), // which we convert to double
     });

  var strings = samples
    .SampleValues       
    .Where(pair => pair.Value is string)
    .Select(pair => new {
       Name  = samples.Name,
       Value = Convert.ToString(pair.Value),
     });

数据结构的主要问题是,您不仅有string和double,还有int:

请注意,转换是可以的:

因此,您可以尝试筛选出字符串项,然后将所有剩余的double和int值转换为double;就你而言:

  var doubles = samples
    .SampleValues       
    .Where(pair => (pair.Value != null) && !(pair.Value is string)) // not string value
    .Select(pair => new {
       Name  = samples.Name,
       Value = Convert.ToDouble(pair.Value), // which we convert to double
     });

  var strings = samples
    .SampleValues       
    .Where(pair => pair.Value is string)
    .Select(pair => new {
       Name  = samples.Name,
       Value = Convert.ToString(pair.Value),
     });

在将值转换为double或stringany之前,应该检查类型。无论如何,此错误不会引发我的错误environment@MarcoSalernoLinq使用延迟执行,您可以在计算IEnumerable@PavelAnikhouski你是真的,我想他写了一个代码让我们扔掉它,我甚至没有检查ahayou应该在将值转换为double或string之前检查类型无论如何,这个错误不会引发我的错误environment@MarcoSalernoLinq使用延迟执行,您可以在计算IEnumerable@PavelAnikhouski你是真的,我想他写了一个代码让我们扔掉它,我甚至没有从示例代码中检查它将在t2处中断,因为您的s.Value==A Str 这将从示例代码的t2处中断,因为s.Value==字符串值,而不能执行字符串值的加倍
  var doubles = samples
    .SampleValues       
    .Where(pair => (pair.Value != null) && !(pair.Value is string)) // not string value
    .Select(pair => new {
       Name  = samples.Name,
       Value = Convert.ToDouble(pair.Value), // which we convert to double
     });

  var strings = samples
    .SampleValues       
    .Where(pair => pair.Value is string)
    .Select(pair => new {
       Name  = samples.Name,
       Value = Convert.ToString(pair.Value),
     });