Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有数组参数和任意元素类型的C#FieldInfo.SetValue_C#_Arrays_Reflection_System.type_Fieldinfo - Fatal编程技术网

带有数组参数和任意元素类型的C#FieldInfo.SetValue

带有数组参数和任意元素类型的C#FieldInfo.SetValue,c#,arrays,reflection,system.type,fieldinfo,C#,Arrays,Reflection,System.type,Fieldinfo,我尝试使用反射设置数组字段,如下所示: FieldInfo field = ... A[] someArray = GetElementsInSomeWay(); field.SetValue(this, someArray); arr2[0] = new object(); 该字段的类型为B[]B继承自A,而B的确切类型在编译时未知。 GetElementsInSomeWay()返回A[],但其中真正的元素都是BGetElementsInSomeWay()是一个库方法,无法更改 我最多只能

我尝试使用反射设置数组字段,如下所示:

FieldInfo field = ...
A[] someArray = GetElementsInSomeWay();
field.SetValue(this, someArray);
arr2[0] = new object();
该字段的类型为
B[]
B
继承自
A
,而
B
的确切类型在编译时未知。
GetElementsInSomeWay()
返回
A[]
,但其中真正的元素都是
B
GetElementsInSomeWay()
是一个库方法,无法更改

我最多只能用
System.Type=field.FieldType.GetElementType()
获取
B
。 但是,我无法将数组强制转换为所需的类型,例如。
someArray作为类型[]
,因为
[]
在声明数组类型之前需要一个确切的类型。还是我在这里遗漏了什么?如果在运行时使用
System.type
变量知道某个类型的数组,我可以声明该类型的数组吗

直接执行此操作会产生以下错误(此处
A
UnityEngine.Component
B
AbilityResult
,也可以是几十个其他类中的一个,所有这些类都从
UnityEngine.Component
继承(可能通过一个长继承链):


经过一番探索,我偶然发现了这个问题:

我的问题的一个可能解决方案是:

A[] someArray = GetElementsInSomeWay();
System.Type type = field.FieldType.GetElementType();
Array filledArray = Array.CreateInstance(type, someArray.Length);
Array.Copy(someArray, filledArray, someArray.Length);
field.SetValue(this, filledArray);
我刚测试过,它能用


但是,我仍然希望避免复制元素。在我的例子中,阵列非常小(最多3-5个元素),但是如果有一个更干净的解决方案,我会很高兴看到它。

经过一些搜索,我偶然发现了这个问题:

我的问题的一个可能解决方案是:

A[] someArray = GetElementsInSomeWay();
System.Type type = field.FieldType.GetElementType();
Array filledArray = Array.CreateInstance(type, someArray.Length);
Array.Copy(someArray, filledArray, someArray.Length);
field.SetValue(this, filledArray);
我刚测试过,它能用


但是,我仍然希望避免复制元素。在我的例子中,数组非常小(最多3-5个元素),但是如果有一个更干净的解决方案的话,那就很好了。

我认为您需要更好地理解数组的变化。像
object[]
string[]
这样的数组已经出现在.NET 1中,比泛型(.NET 2)早了很长时间。否则,它们可能被称为
Array
Array

现在,我们都知道任何
字符串
都是
对象
。如果这一事实意味着,对于某些“构造”
Xxx
,任何
Xxx
都是
Xxx
,那么我们称之为。自.NET 4以来,一些通用接口和通用委托类型可以是covarinat,并且在其定义中用
out
关键字标记,如中所示

public interface IEnumerable<out T>
{
  // ...
}
因此,
T[]
在.NET中是协变的。但是我刚才不是说我可以写(比如
in
而不是
out
)到一个数组吗?那么,如果我继续这样做会怎么样:

FieldInfo field = ...
A[] someArray = GetElementsInSomeWay();
field.SetValue(this, someArray);
arr2[0] = new object();
我正在尝试将一个不是
字符串的
对象
放入第0个插槽。上面的行必须编译(编译时类型的
arr2
object[]
)。但它也必须提出一个例外运行时间。这就是数组和协方差的问题

那么,逆变呢?试试这个:

object[] arrA = { new object(), DateTime.Now, "hello", };
string[] arrB = arrA;  // won't compile, no cotravariance
object[]
string[]
进行显式转换仍然无法在运行时工作

现在,您的问题的答案是:您正在尝试对数组应用逆变换
AbilityResult
Component
,但这并不意味着
Component[]
AbilityResult[]
。编写
GetElementsInSomeWay()
方法的人选择创建
新组件[]
。即使他输入的所有组件都是
AbilityResult
,仍然没有相反的结果。
GetElementsInSomeWay()
的作者可以选择创建一个
新功能result[]
。由于.NET数组的协方差,他仍然可以使用返回类型
组件[]

要学习的课程:数组的实际类型(运行时类型,如
.GetType()
所示)不会因为您强制转换而改变。NET允许协方差(类型为
Component[]
的变量可能包含实际类型为
AbilityResult[]
的对象)。最后,.NET不允许逆变(类型为
AbilityResult[]
的变量从不包含对实际类型为
Component[]
的对象的引用)


希望这有帮助。否则,我的答案应该会给你一些术语,你可以在谷歌上找到比我更好的解释。

我认为你需要更好地理解数组的变化。像
object[]
string[]
这样的数组已经出现在.NET 1中,比泛型(.NET 2)早了很长时间。否则,它们可能被称为
Array
Array

现在,我们都知道任何
字符串
都是
对象
。如果这一事实意味着,对于某些“构造”
Xxx
,任何
Xxx
都是
Xxx
,那么我们称之为。自.NET 4以来,一些通用接口和通用委托类型可以是covarinat,并且在其定义中用
out
关键字标记,如中所示

public interface IEnumerable<out T>
{
  // ...
}
因此,
T[]
在.NET中是协变的。但是我刚才不是说我可以写(比如
in
而不是
out
)到一个数组吗?那么,如果我继续这样做会怎么样:

FieldInfo field = ...
A[] someArray = GetElementsInSomeWay();
field.SetValue(this, someArray);
arr2[0] = new object();
我正在尝试将一个不是
字符串的
对象
放入第0个插槽。上面的行必须编译(编译时类型的
arr2
object[]
)。但它也必须提出一个例外运行时间。这就是数组和协方差的问题

那么,逆变呢?试试这个:

object[] arrA = { new object(), DateTime.Now, "hello", };
string[] arrB = arrA;  // won't compile, no cotravariance
object[]
string[]
进行显式转换仍然无法在运行时工作

现在,您的问题的答案是:您正在尝试对数组应用逆变换<代码>能力结果
组件
,但这并不意味着
组件[]
能力