【问题标题】:Why string[] is interpreted as object[], not as object, but we can assign object obj = new string[]?为什么string[]被解释为object[],而不是object,但我们可以赋值object obj = new string[]?
【发布时间】:2016-03-13 03:39:26
【问题描述】:

我目前正在从this video 学习Reflection 后期绑定。

当我复制视频中的代码时,有一部分让我感到困惑。就是使用Invoke方法的时候:

MethodInfo getFullNameMethod = customerType.GetMethod("GetFullName");
string[] parameters = new string[2];
parameters[0] = "First";
parameters[1] = "Last";

//here is where I got confused...
string fullName = (string)getFullNameMethod.Invoke(customerInstance, parameters);

据我所见(也显示在视频中)Invoke 的输入参数为(object, object[]),并且没有输入参数(object, object) 的重载方法。

这里传递的是(object, string[])。因此,起初我预计会出现编译错误,因为我认为string[]object 而不是object[]。但是....没有编译错误。

这让我很困惑:为什么string[]object[] 而不是object(毕竟每个Type 都是C# 派生自object)?我们不能像这样将string[] 分配为object 吗?

object obj = new string[3]; //this is OK

string[] 怎么可能既是 object 又是 object[]?使用其他数据类型,比如int,作为类比,我永远不会期望变量同时为intint[]

有人能告诉我吗?


Here is my full code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace ConsoleApplication2 {
    class Program {
        static void Main(string[] args) {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            Type customerType = executingAssembly.GetType("ConsoleApplication2.Customer");
            object customerInstance = Activator.CreateInstance(customerType);
            MethodInfo getFullNameMethod = customerType.GetMethod("GetFullName");
            string[] parameters = new string[2];
            parameters[0] = "First";
            parameters[1] = "Last";
            string fullName = (string)getFullNameMethod.Invoke(customerInstance, parameters);
            Console.WriteLine(fullName);
            Console.ReadKey();
        }
    }

    class Customer {
        public string GetFullName(string FirstName, string LastName) {
            return FirstName + " " + LastName;
        }
    }
}

【问题讨论】:

  • 首先,.NET 中的每个classstruct(包括每个数组)最终都派生自object,因此string[] 可以转换为object。其次,为了与 Java 兼容,.NET 中的数组是“协变的”,这意味着如果 X 对 Y 有引用转换,则 X 类型的数组可以转换为 Y 类型的数组。因为string 派生自object , string[] 可以转换为object[]
  • @MichaelLiu 这应该是答案! :) 您能否再解释一下“为了与 Java 兼容,.NET 中的数组是协变的”?因为我对Java不太熟悉..
  • Eric Lippert 有一篇简短的博客文章讨论了它:blogs.msdn.microsoft.com/ericlippert/2007/10/17/…
  • @MichaelLiu 好的,会看的。再次感谢。
  • 昨天重复的stackoverflow.com/questions/35876463/…,以及之前的许多问题。

标签: c# arrays object reflection


【解决方案1】:

根据MSDN 中的第 12.5 节

对于任意两个引用类型 A 和 B,如果隐式引用 转换(第 6.1.4 节)或显式引用转换(第 6.1.4 节) 6.2.3)存在从A到B,那么同样的引用转换也存在从数组类型A[R]到数组类型B[R],其中R是任意的 给定等级说明符(但对于两种数组类型都相同)。 这个 关系称为数组协方差

以下代码完全有效。

string[] items = new string[] {"A", "B", "C"};      
object[] objItems = items; 

这就是为什么在您的情况下,传递string[] 是有效的,并将转换为object[]

【讨论】:

  • 谢谢,这解释了。 :)
  • @Ian 我的荣幸 :-)
猜你喜欢
  • 2010-10-26
  • 2018-10-29
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
相关资源
最近更新 更多