鉴于此代码:
class C
{
    C()
    {
        Test<string>(A); // fine
        Test((string a) => {}); // fine
        Test((Action<string>)A); // fine
        Test(A); // type arguments cannot be inferred from usage!
    }
    static void Test<T>(Action<T> a) { }
    void A(string _) { }
}
编译器抱怨Test(A)无法弄清楚T是string.
这对我来说似乎是一个非常简单的案例,我发誓我在其他通用实用程序和扩展函数中依赖于更复杂的推理.我在这里错过了什么?
更新1:这是在C#4.0编译器中.我在VS2010中发现了这个问题,上面的示例来自我在LINQPad 4中制作的最简单的repro.
更新2:在可用的列表中添加了更多示例.
如果编译器可以推断它,C#不要求您指定泛型类型参数,例如:
List<int> myInts = new List<int> {0,1,1,
    2,3,5,8,13,21,34,55,89,144,233,377,
    610,987,1597,2584,4181,6765};
//this statement is clunky
List<string> myStrings = myInts.
    Select<int,string>( i => i.ToString() ).
    ToList<string>();
//the type is inferred from the lambda expression
//the compiler knows that it's taking an int and 
//returning a string
List<string> myStrings = myInts.
    Select( i => i.ToString() ).
    ToList();
这是匿名类型所必需的,你不知道类型参数是什么(在intellisense中它显示为'a),因为它是由编译器添加的.
类级别类型参数不允许您这样做:
//sample generic class
public class GenericDemo<T> 
{
    public GenericDemo ( T value ) 
    {
        GenericTypedProperty = value;
    }
    public T GenericTypedProperty {get; set;} …为什么C#推断方法的泛型参数而不是构造函数?
new Tuple<int, int>(5, 5) 与 Tuple.Create(5, 5)
我有许多是从类派生的类BaseClass,其中BaseClass仅仅有一个'ID属性.
我现在需要对其中一些对象的集合进行区分.我为每个子类反复提供以下代码:
public class PositionComparer : IEqualityComparer<Position>
{
    public bool Equals(Position x, Position y)
    {
        return (x.Id == y.Id);
    }
    public int GetHashCode(Position obj)
    {
        return obj.Id.GetHashCode();
    }
}
鉴于逻辑只是基于Id,我想创建一个单一的比较器来减少重复:
public class BaseClassComparer : IEqualityComparer<BaseClass>
{
    public bool Equals(BaseClass x, BaseClass y)
    {
        return (x.Id == y.Id);
    }
    public int GetHashCode(BaseClass obj)
    {
        return obj.Id.GetHashCode();
    }
}
但这似乎没有编译:
  IEnumerable<Position> positions = GetAllPositions();
  positions = allPositions.Distinct(new BaseClassComparer())
...因为它说它无法转换BaseClass为Position.为什么比较器会强制执行此Distinct()调用的返回值?
作为"javaland"程序员,我习惯于工厂方法和多个构造函数.我对工厂模式的主要用途是将决策延迟到运行时,在实例化期间执行某种副作用或限制或隐藏具体类型.当我深入研究C#时,我看到越来越多的API混合了多个构造函数和静态Create方法.
例如,XmlReader和XmlTextReader.XmlWriter和XmlTextWriter.
我的问题是:
Create方法有什么特别的东西,或者它只是一个约定(比如java :) getInstance?Create方法接受XmlWriterSettings参数XmlWriter而没有构造函数XmlTextWriter具有相同的目的?而另一方面,为什么只有构造函数接受Encoding参数呢?方法有类型参数.为什么构造函数没有类型参数?
我认为有几个(不是很多)例子可供它们使用.我目前的问题如下:
internal class ClassA
{
   private readonly Delegate _delegate;
   public ClassA<T>(Func<T> func)
   {
     _delegate = func;
   }
}
A Delegate对我的班级来说已经足够了.但要将其作为方法组传递,我需要将参数定义为a Func<T>.
这可能吗?
var cats = catsource.Select(c => new
{
    CatId = c.catId,
    Name = c.Name,
}).ToList();
var myCatObject = new CatData(cats);
这不起作用,因为编译器说它无法转换cats为List<T>.
cats是一种匿名类型,CatData是:
public class CatData<T>
{
    public int total;
    public int records;
    public List<T> records;
    public CatData(List<T> dataObjects, int totalRecords, int numberOfRows)
    {
        total = (int)Math.Ceiling((double)totalRecords / numberOfRows);
        records = totalRecords;
        rows = dataObjects;
    }
}
有任何想法吗?
编辑:
所以我已经完成了这个代码,但仍然存在一个问题:
 public class CatData
 {
     public int total;
     public int records;
     public List<T> rows;
     private …