[英]Automatically creating type of method
How can I automatically initialize the type of a method in C#? 如何在C#中自动初始化方法的类型?
For instance, 例如,
List<int> MyIntList()
{
List<int> returnList = new List<int>();
return returnList;
}
I've basically created an instance of the return type, to return. 我基本上已经创建了返回类型的实例来返回。 Is there something in the C# language that infers the type to return, so that an instance doesn't have to be created within the method, such as:
C#语言中是否有某些东西可以推断出要返回的类型,所以不必在方法中创建实例,例如:
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;
}
Simply put, can I prevent List<int>
in the example from being typed more than once, and let the compiler infer the rest? 简而言之,我可以防止示例中的
List<int>
多次键入,然后让编译器推断其余部分吗?
If I understand you correctly you mean something like this: 如果我正确理解您的意思,则是这样的:
List<int> MyIntList()
{
var result = new List<int>();
return result;
}
var
is just a placeholder for the actual type List<int>
or whatever you assign to it. var
只是实际类型List<int>
或您为其分配的任何内容的占位符。 In contrast to JavaScript in C# the keyword relate to a strong type so you can deal with it as with any other type, it automatically lists the correct members appropriate for that type. 与C#中的JavaScript相反,关键字与强类型相关,因此您可以像处理其他任何类型一样处理它,它会自动列出适合该类型的正确成员。
EDIT: To answer why you can´t do what you want: The method-signature often states that an interface is returned, however the actual type doesn´t matter at all. 编辑:回答为什么您不能做自己想做的事情:方法签名通常指出返回了一个接口,但是实际类型根本不重要。 Usually you won´t care if the method actually returns a
List
, a Dictionary
or anything else as long as it implements IEnumerable
for example. 通常,只要方法实现
IEnumerable
,您就不会在意该方法是否实际上返回List
, Dictionary
或其他任何东西。 However if you´d force the compiler to return a List<int>
instead of an IEnumerable<int>
for example you lose all the benfits of interfaces as you allways infer the actual type insteaf of the interface. 但是,例如,如果您强迫编译器返回
List<int>
而不是IEnumerable<int>
,则当您始终推断接口的实际类型为insteaf时,将会丢失接口的所有好处。 Having said this the consumer of the mthod could even add or remove elements from/to the list being returned. 话虽如此,方法的使用者甚至可以从返回的列表中添加元素或从中删除元素。 If you´d use the mentioned interface all you return is something that represents a list of values which can be enumerated.
如果您使用提到的接口,则返回的所有内容都代表可以枚举的值的列表。
Also consider this case: 还要考虑这种情况:
List<int> MyIntList()
{
if (anyCondition)
{
var result = new List<int>();
return result;
}
else
{
var result = new int[0];
return result
}
}
What type should the compiler infer in this case? 在这种情况下,编译器应推断什么类型? The signature of the method is a contract to the outside which determines which things you can do with the result.
该方法的签名是与外部的合同,它确定您可以对结果执行哪些操作。
Perhaps this: 也许这:
private static T GetSomething<T>() where T: new()
{
return new T();
}
But then you will need to pass the type as typeparameter T
: 但是然后您需要将类型作为typeparameter
T
传递:
var x = GetSomething<List<int>>();
You're looking for something like 您正在寻找类似的东西
auto MyIntList()
{
return new List<int>();
}
Having the compiler infer the return value and replace auto
with List<int>
让编译器推断返回值,并用
List<int>
替换auto
This is not possible with the latest version of C# (6.0) 最新版本的C#(6.0)无法实现
I can't give a precise answer as to whether the C# specification disallows it, but I can provide examples. 对于C#规范是否不允许它,我无法给出确切的答案,但是我可以提供示例。 First, what if you want a method to return an interface?
首先,如果要一种方法返回接口怎么办? In your examples you used
List<int>
but what if you changed it to IList<int>
? 在示例中,您使用了
List<int>
但是如果将其更改为IList<int>
怎么办? Or consider this simplified example: 或者考虑以下简化示例:
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");
}
You cannot create an instance of an interface. 您不能创建接口的实例。 So this is wrong:
所以这是错误的:
public IFoo BadFooCreate() => new IFoo(); // won't compile
But this would work, though it begs the question of how the compiler know you want Foo1 to be the particular IFoo that is returned: 但这将起作用,尽管它引发了一个问题,即编译器如何知道您希望Foo1成为返回的特定IFoo:
public IFoo GoodFooCreate() => new Foo1(); // compiles okay
This works too: 这也适用:
public IFoo GoodFooCreate() => Foo2.Create(); // compiles okay
But since Foo2 has a private constructor, this would not work: 但是由于Foo2具有私有构造函数,因此无法使用:
public IFoo BadFoo2Create() => new Foo2(); // won't compile
Another set of examples revolve around abstract classes. 另一组示例围绕抽象类。 Consider:
考虑:
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";
}
This would be wrong because you can't create an instance of an abstract class: 这将是错误的,因为您无法创建抽象类的实例:
public Animal BadAnimalCreate() => new Animal(); // won't compile
But this works perfectly fine: 但这工作得很好:
public Animal GoodAnimalCreate() => new Dog(); // compiles okay
Although again if the compiler were to automatically create a type for a lazy programmer, how would the compiler know to use Dog() and not Cat()? 尽管如果编译器再次为懒惰的程序员自动创建类型,编译器又将如何使用Dog()而不是Cat()? Letting the compiler pick on your behalf encroaches on violating the Principle of Least Astonishment .
让编译器代表您选择违反了“最小惊讶原则” 。 There's being lazy and then there's abdicating your responsibility.
有一个懒惰,然后放弃了你的责任。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.