自动创建方法类型

Automatically creating type of method

如何在 C# 中自动初始化方法的类型?

例如,

List<int> MyIntList()
{
    List<int> returnList = new List<int>();
    return returnList;
}

我基本上已经创建了一个 return 类型的实例,到 return。 C#语言中有没有把类型推断为return,从而不必在方法内创建实例,如:

List<int> MyIntList()
{
    // invalid - "this" refers to the containing class,
    // but looking for something that refers to the containing method.
    this = new List<int>();
    return this;
}

简单的说,我能不能让例子中的List<int>不被多次输入,而让编译器去推断剩下的呢?

如果我理解正确的话,你的意思是这样的:

List<int> MyIntList()
{
    var result = new List<int>();
    return result;
}

var 只是实际类型 List<int> 或您分配给它的任何内容的占位符。与 C# 中的 JavaScript 相比,该关键字与强类型相关,因此您可以像处理任何其他类型一样处理它,它会自动列出适合该类型的正确成员。

编辑:回答为什么你不能做你想做的事:方法签名通常声明接口是 returned,但是实际类型根本不重要。通常你不会关心该方法是否实际上 return 是 ListDictionary 或其他任何东西,只要它实现了 IEnumerable。但是,如果您强制编译器 return 一个 List<int> 而不是 IEnumerable<int> 例如,您将失去接口的所有好处,因为您总是推断接口的实际类型而不是接口。话虽如此,该方法的使用者甚至可以添加或删除元素 from/to 正在 returned 的列表。如果你要使用提到的接口,你 return 就是代表可以枚举的值列表的东西。

也考虑这个案例:

List<int> MyIntList()
{
    if (anyCondition)
    {
        var result = new List<int>();
        return result;
    }
    else 
    {
        var result = new int[0];
        return result
    }
}

在这种情况下,编译器应该推断出什么类型?方法的签名是与外部的契约,它决定了您可以对结果执行哪些操作。

您正在寻找类似

的内容
auto MyIntList()
{
    return new List<int>();
}

让编译器推断 return 值并将 auto 替换为 List<int>

最新版本的 C# (6.0) 无法做到这一点

也许是这样:

private static T GetSomething<T>() where T: new()
{
    return new T();
}

但是你需要将类型作为类型参数传递 T:

var x = GetSomething<List<int>>();

关于 C# 规范是否不允许,我无法给出准确的答案,但我可以提供示例。首先,如果你想要一个 return 接口的方法怎么办?在您的示例中,您使用了 List<int>,但如果将其更改为 IList<int> 会怎样?或者考虑这个简化的例子:

public interface IFoo
{
    void Bar();
}
public class Foo1 : IFoo
{
    public Foo1() { }
    public void Bar() => Console.WriteLine("Foo1.Bar");
}
public class Foo2 : IFoo
{
    private Foo2() { }
    public static Foo2 Create => new Foo2();
    public void Bar() => Console.WriteLine("Foo2.Bar");
}

您不能创建接口的实例。所以这是错误的:

public IFoo BadFooCreate() => new IFoo(); // won't compile

但这会起作用,尽管它回避了编译器如何知道您希望 Foo1 成为 returned:

的特定 IFoo 的问题
public IFoo GoodFooCreate() => new Foo1(); // compiles okay

这也有效:

public IFoo GoodFooCreate() => Foo2.Create(); // compiles okay

但是因为 Foo2 有一个私有构造函数,所以这行不通:

public IFoo BadFoo2Create() => new Foo2(); // won't compile

另一组示例围绕抽象 classes。考虑:

public abstract class Animal
{
    public Animal() { }
    public virtual string Name => "Generic Animal";
    public abstract string Speak();
}
public class Dog : Animal
{
    public override string Name => "Dog";
    public override string Speak() => "Bark";
}
public class Cat : Animal
{
    public override string Name => "Cat";
    public override string Speak() => "Meow";
}

这是错误的,因为您不能创建抽象的实例 class:

public Animal BadAnimalCreate() => new Animal(); // won't compile

但这工作得很好:

public Animal GoodAnimalCreate() => new Dog(); // compiles okay

虽然如果编译器自动为懒惰的程序员创建类型,编译器怎么知道使用 Dog() 而不是 Cat()?让编译器代表您进行选择侵犯了 Principle of Least Astonishment。有懒惰,然后有放弃你的责任。