【问题标题】:Unity3D - Why do we have to add some parameters outside of braces? [duplicate]Unity3D - 为什么我们必须在大括号之外添加一些参数? [复制]
【发布时间】:2017-10-24 18:33:14
【问题描述】:

我知道许多编程和脚本语言,但我以前从未见过这样的东西:

camera = GetComponentInParent<Camera>();

这在 C# 中正常吗?为什么我们不必像这样传递参数Camera

camera = GetComponentInParent(Camera);

我在哪里可以告诉自己为什么会这样?

【问题讨论】:

标签: c# unity3d


【解决方案1】:

第一个版本中的参数是type parameter。类型参数不是指值,而是指类型。这用于泛型方法和类,允许类中使用的类型具有(一定的)灵活性,同时保持静态类型。

比较通用列表类List&lt;T&gt;。您必须传递类型参数以强制您不能添加其他类型的实例。

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&lt;T&gt;.Add 具有签名void Add(T item) 并创建List&lt;int&gt; 将类型参数T 固定为int

第二种语法

如果 Camera 是一种类型,则此语法不是有效的 C#。编译器会抛出错误

Camera 是一种类型,在当前上下文中无效。

如果GetComponentInParent 将采用Type 参数(Type 类型的参数,而不是泛型类型参数),您可以这样称呼它

GetComponentInParent(typeof(Camera))

但是你会失去泛型的优点,即GetComponentInParent 的返回类型不会是Camera,而是一个不太专业的类型。如果GetComponentInParent 可以返回的组件没有共同的祖先,它甚至可能返回一个object,而通用版本可能有签名

T GetComponentInParent<T>()

哪种情况下它会返回正确的类型而不需要转换结果。

【讨论】:

    【解决方案2】:

    尖括号内的参数是一个类型参数,用于所谓的“泛型”。 GetComponentsInParent 方法使用 C# 泛型功能根据泛型类型参数具有不同的返回类型。当您使用列表时,您可能经常使用这个概念而没有过多考虑它。如果我有一个 Camera 对象列表,我将创建它的方式是使用 var cameras = new List&lt;Camera&gt;(); 而不是 var cameras = new List(Camera);

    GetComponentsInParent 方法的签名为 T[] GetComponentsInParent&lt;T&gt;()。如果要在参数列表中采用类型而不是使用泛型,则签名必须是 object[] GetComponentsInParent(type T) 或可能是 GameObject[] GetComponentsInParent(type T) 并且您的代码有责任将返回的数组元素转换为您实际需要的对象.泛型帮助我们使这些场景更加简洁。

    有关 C# 中泛型类型的更多信息,请参阅https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/

    【讨论】:

      猜你喜欢
      • 2017-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      • 2021-12-19
      相关资源
      最近更新 更多