相关疑难解决方法(0)

为什么Func <T>与Func <IEnumerable <T >>不明确?

这个让我感到沮丧,所以我想我会在这里问,希望C#guru可以向我解释.

为什么这段代码会产生错误?

class Program
{
    static void Main(string[] args)
    {
        Foo(X); // the error is on this line
    }

    static String X() { return "Test"; }

    static void Foo(Func<IEnumerable<String>> x) { }
    static void Foo(Func<String> x) { }
}
Run Code Online (Sandbox Code Playgroud)

有问题的错误:

Error
    1
    The call is ambiguous between the following methods or properties:
'ConsoleApplication1.Program.Foo(System.Func<System.Collections.Generic.IEnumerable<string>>)' and 'ConsoleApplication1.Program.Foo(System.Func<string>)'
    C:\Users\mabster\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs
    12
    13
    ConsoleApplication1
Run Code Online (Sandbox Code Playgroud)

我使用的是什么类型并不重要 - 如果在该代码中用"int"替换"String"声明,您将得到相同类型的错误.这就像编译器不能告诉之间的区别Func<T>Func<IEnumerable<T>>.

有人可以对此有所了解吗?

c# generics

20
推荐指数
2
解决办法
2859
查看次数

为什么编译器无法推断方法的类型?

在以下代码中:

public class A
{
    public decimal Decimal { get; set; }
}

public decimal Test()
{
    return new List<A>().Sum(SumDecimal);
}

public decimal SumDecimal(A a)
{
    return a.Decimal;
}
Run Code Online (Sandbox Code Playgroud)

该行return new List<A>().Sum(SumDecimal);有一个错误,指出这SumDecimal是一个模糊的调用.

为什么编译器无法推断出类型SumDecimal.但是,以下工作:

return new List<A>().Sum((Func<A, decimal>) SumDecimal);
Run Code Online (Sandbox Code Playgroud)

当然,通常的lambda方式也适用:

return new List<A>().Sum(x => SumDecimal(x));
Run Code Online (Sandbox Code Playgroud)

在更多实验中,如果我编写自己的扩展方法:

public static class MyExtensions
{
    public static T MySum<T, T2>(this IEnumerable<T2> ie, Func<T2, T> d)
    {
        return default(T);
    }
}
Run Code Online (Sandbox Code Playgroud)

并称之为,编译器推断得很好:

return new List<A>().MySum(SumDecimal);
Run Code Online (Sandbox Code Playgroud)

我看到,IEnumerable<T>.Sum目前超载int, …

c# linq ienumerable

18
推荐指数
0
解决办法
181
查看次数

将扩展方法组转换为具有泛型类型的委托

我在IDataReader上有两个扩展方法,具有以下签名:

internal static List<T> GetList<T>(this IDataReader reader, Func<string, T> del)

internal static double? GetDoubleOrNull(this IDataReader reader, string columnName)
Run Code Online (Sandbox Code Playgroud)

GetDoubleOrNull 没有任何重载.

在其他地方,我能做到

Func<string, double?> del = reader.GetDoubleOrNull;

var x = reader.GetList(del);
Run Code Online (Sandbox Code Playgroud)

要么

var x = reader.GetList<double?>(reader.GetDoubleOrNull);
Run Code Online (Sandbox Code Playgroud)

或者只是传入一个类似的实例方法

public double? blah(string s)

var x = reader.GetList(blah);
Run Code Online (Sandbox Code Playgroud)

但我不能这样做

var x = reader.GetList(reader.GetDoubleOrNull);
Run Code Online (Sandbox Code Playgroud)

编译器给出错误

cannot convert from 'method group' to 'System.Func<string,double?>'
Run Code Online (Sandbox Code Playgroud)

我不明白这一点.我认为既然没有重载GetDoubleOrNull,就不会有重载决策,它可以从方法签名推断出类型参数.

真正令人困惑的部分是它在传入时的工作方式blah.

c# generics extension-methods delegates internals

13
推荐指数
2
解决办法
2650
查看次数

将IEnumerable数值作为参数传递给方法

我正在玩一个非常简单的程序来获取一系列双打并返回标准偏差.这部分工作但我想让代码更可重用.我想这样做,所以该方法可以接受任何类型的参数,可以被认为是数字并返回标准偏差而不是硬编码双重类型(就像我最初在这个程序中做的那样).如何解决这个问题以及适当的术语是什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


    namespace ConsoleApplication5
    {
        class Program
        {
            static void Main(string[] args)
            {
                double[] avg = { 3.4, 55.6, 10.0, 4.5, 2, 2 };
                double x = avg.Average();
                //first round of testing
                Console.WriteLine("The average of the first array is below ");
                Console.WriteLine(x);
                Console.WriteLine("below should be the standard deviation!");
                Console.WriteLine(CalculateStandardDeviation(avg));
                Console.ReadLine();
                int[] intAvg = { 4, 3, 5, 6, 2 };
                double secondAvg = intAvg.Average();
                Console.WriteLine("The average of the second array is below "); …
Run Code Online (Sandbox Code Playgroud)

c# visual-studio-2010

9
推荐指数
2
解决办法
2万
查看次数

重载的方法组参数会混淆重载决策?

以下调用重载Enumerable.Select方法:

var itemOnlyOneTuples = "test".Select<char, Tuple<char>>(Tuple.Create);
Run Code Online (Sandbox Code Playgroud)

失败并出现歧义错误(为清晰起见,删除了名称空间):

The call is ambiguous between the following methods or properties: 
'Enumerable.Select<char,Tuple<char>>
           (IEnumerable<char>,Func<char,Tuple<char>>)'
and 
'Enumerable.Select<char,Tuple<char>>
          (IEnumerable<char>, Func<char,int,Tuple<char>>)'
Run Code Online (Sandbox Code Playgroud)

我当然可以理解为什么明确指定类型参数会导致歧义(两个都会应用重载),但是在这样做后我没有看到.

对我来说似乎很清楚,目的是调用第一个重载,方法组参数解析为Tuple.Create<char>(char).第二个重载不应该适用,因为没有任何 Tuple.Create重载可以转换为期望的Func<char,int,Tuple<char>>类型.我猜测编译器很困惑Tuple.Create<char, int>(char, int),但它的返回类型是错误的:它返回一个二元组,因此不能转换为相关Func类型.

顺便说一句,以下任何一个使编译器开心:

  1. 为method-group参数指定一个type-argument :( Tuple.Create<char>也许这实际上是一个类型推断问题?).
  2. 使参数成为lambda表达式而不是方法组:x => Tuple.Create(x).(在Select通话中使用类型推断很好).

不出所料,尝试以Select这种方式调用其他重载也会失败:

var itemIndexTwoTuples = "test".Select<char, Tuple<char, int>>(Tuple.Create);
Run Code Online (Sandbox Code Playgroud)

这里的确切问题是什么?

c# method-group overload-resolution c#-4.0

8
推荐指数
2
解决办法
2231
查看次数