【问题标题】:Extension Method not compiling (No defintion for type 'string')扩展方法未编译(没有“字符串”类型的定义)
【发布时间】:2011-01-11 09:25:42
【问题描述】:

我正在尝试使用下面的代码将字节转换为 KB/MB/GB,但是,我似乎无法让它工作。配额的值为60000000000。

    public static double BytesToKilobytes(this Int32 bytes)
    {
        return bytes / 1000d;
    }

    public static double BytesToMegabytes(this Int32 bytes)
    {
        return bytes / 1000d / 1000d;
    }

    public static double BytesToGigabytes(this Int32 bytes)
    {
        return bytes / 1000d / 1000d / 1000d;
    }

    void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error != null)
            return;

        XDocument xDocument = XDocument.Parse(e.Result);

        listBox1.ItemsSource = from query in xDocument.Descendants("service")
                               select new Service
                               {
                                   type = query.Attribute("type").Value,
                                   id = query.Element("id").Value,
                                   plan = query.Element("username").Value,
                                   quota = query.Element("quota").Value.BytesToGigabytes,                                   };
    }

以上代码产生的错误是:

"'string' 不包含'BytesToGigabytes' 的定义,并且找不到接受'string' 类型的第一个参数的扩展方法'BytesToGigabytes'(您是否缺少 using 指令或程序集引用?)"

【问题讨论】:

  • 可能不是你的问题,但是如果 quota 的值是 60*10^9,它不适合 Int32。您需要在这里使用 Int64(又名 long)。

标签: c# linq itemssource


【解决方案1】:

由于配额是一个字符串,所以你必须先将其解析为一个数字:

quota = Decimal.Parse(query.Element("quota").Value).BytesToGigabytes()

由于数字太大,无法容纳 32 位整数,您必须使用小数:

public static Decimal BytesToGigabytes(this Decimal bytes) {
  return bytes / 1000m / 1000m / 1000m;
}

也可以使用 Int64,但该方法会截断结果,例如返回 3 GB 而不是 3.9 GB。

【讨论】:

  • 嗨 Guffa,我尝试了您的解决方案,但是它引发了以下错误:“无法将类型 'decimal' 隐式转换为 'string'”。
  • @cvandal:quota 是字符串成员吗?然后,您必须在分配之前将值格式化为字符串。
  • 啊,是的,我错过了 :) 完美!
【解决方案2】:

这是因为Value 是一个字符串,而扩展方法是为Int32 声明的。在调用扩展方法之前,您需要将 Value 转换为 Int32

例子:

void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    Func<string, Int64> convertToInt64 = s =>
    {
       Int64 result;
            // replace 0 with whatever default you want
       return Int64.TryParse(s, out result) ? result : 0;
    };
    if (e.Error != null) return; 
    XDocument xDocument = XDocument.Parse(e.Result); 
    listBox1.ItemsSource = from query in xDocument.Descendants("service") 
                           select new Service 
                           { 
                               type = query.Attribute("type").Value, 
                               id = query.Element("id").Value, 
                               plan = query.Element("username").Value, 
                               quota = convertToInt64(query.Element("quota").Value)
                                           .BytesToKilobytes()
                           };
}

这也意味着应该为Int64声明扩展方法:

public static double BytesToKilobytes(this Int64 bytes) 

【讨论】:

  • 这是不可能的。该值太大,无法放入 Int32
  • @Guffa:是的,应该是Int64
【解决方案3】:

不知道你的事件参数是什么,错误是相当简单的。

对于一种字符串类型,BytesToGigabytes 没有扩展名。

所以 query.Element("quota") 返回一个字符串。如果你解析它(int.Parse()int.TryParse() 那么你应该有更多的运气。

【讨论】:

    【解决方案4】:

    虽然有几个错误 .. 你应该除以 1024 ...并将值转换为 Int .. 见下文。

     public static double BytesToKilobytes(this Int32 bytes)
        {
            return bytes / 1024d;
        }
    
        public static double BytesToMegabytes(this Int32 bytes)
        {
            return bytes / 1024d / 1024d;
        }
    
        public static double BytesToGigabytes(this Int32 bytes)
        {
            return bytes / 1024d / 1024d / 1024d;
        }
    
        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
                return;
    
            XDocument xDocument = XDocument.Parse(e.Result);
    
            listBox1.ItemsSource = from query in xDocument.Descendants("service")
                                   select new Service
                                   {
                                       type = query.Attribute("type").Value,
                                       id = query.Element("id").Value,
                                       plan = query.Element("username").Value,
                                       quota = Convert.ToInt32(query.Element("quota").Value).BytesToGigabytes(),                                   };
        }
    

    希望对你有帮助

    【讨论】:

    • 一千字节就是1000字节,你说的是千字节。 OP 可能实际上想要千字节而不是千字节,但这还不确定。单位千字节通常用于两种单位。
    • @Guffa ...我确认我对 SO 的热爱 ...我从来不知道 kibibyte 直到你提到它...学习永无止境 ...
    猜你喜欢
    • 2017-03-26
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多