我知道很多编程和脚本语言,但我之前从未见过这样的东西:
camera = GetComponentInParent<Camera>();
这在C#中是否正常?为什么我们不必像这样传递参数Camera
:
camera = GetComponentInParent(Camera);
我在哪里可以告诉自己为什么会这样?
答案 0 :(得分:3)
第一个版本中的参数是type parameter。类型参数不是指值,而是指类型。这用于泛型方法和类,它们允许(某种)灵活地使用类中使用的类型,同时保持静态类型。
比较通用列表类List<T>
。您必须传递一个类型参数,以强制您无法添加其他类型的实例。
List<int> myList = new List<int>();
myList.Add(1);
myList.Add(2);
foreach(var item in myList)
{
// ...
}
由于myList
具有类型参数int
,您和编译器(和智能感知器)都知道,myList
中的所有内容都是int
。因此item
将具有int
类型。另一方面,以下是不可能的
myList.Add("FooBar");
由于List<T>.Add
具有签名void Add(T item)
,并且创建List<int>
会将类型参数T
修复为int
。
如果Camera
是一种类型,则此语法无效C#。编译器将抛出错误
Camera
是一种类型,在当前上下文中无效。
如果GetComponentInParent
采用Type
参数(Type
类型的参数,而不是通用类型参数),您可以将其称为
GetComponentInParent(typeof(Camera))
但是你会失去泛型的优点,即GetComponentInParent
的返回类型不是Camera
,而是一种不太专业的类型。如果GetComponentInParent
可以返回的组件没有共同的祖先,它甚至可以返回object
,而通用版本可能具有签名
T GetComponentInParent<T>()
ich,在不需要强制转换结果的情况下,它会返回正确的类型。
答案 1 :(得分:2)
尖括号内的参数是一个类型参数,用于所谓的&#34;泛型&#34;。 GetComponentsInParent
方法使用C#泛型功能根据泛型类型参数具有不同的返回类型。当您使用列表时,您可能经常使用此概念而不必过多考虑它。如果我有一个Camera对象列表,我将创建它的方式是说var cameras = new List<Camera>();
而不是var cameras = new List(Camera);
。
GetComponentsInParent
方法的签名为T[] GetComponentsInParent<T>()
。如果是在参数列表中使用类型而不是使用泛型,则签名必须是object[] GetComponentsInParent(type T)
或GameObject[] GetComponentsInParent(type T)
,并且代码负责投射返回的数组元素到您实际需要的对象中。泛型帮助我们使这些场景更加清洁。
有关C#中泛型类型的更多信息,请参阅https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/