none
数组直接赋值问题 RRS feed

  • 问题

  • int[] n = { 1, 2, 3 };
    object[] o = n; //为什么这样不可以?
    以上赋值不可以,但是下面的赋值却可以:(Chinese类是Person类的子类)
    Chinese[] cn = { new Chinese() { Name = "zs" }, new Chinese() { Name = "ls" } };
    Person[] per = cn;//为什么这样可以?数组不都是引用类型吗?object[] o=n;却不可以
    求解释。不要只来一句:int是值类型,Chinese是引用类型。
    • 已移动 Paul Zhou 2011年4月26日 10:38 C# (发件人:.NET Framework 一般性问题讨论区)
    2011年4月22日 7:30

答案

  • int 没有继承Object类


    胡超
    2011年4月26日 11:20
  • 您好

    int 無法轉為 object,您可以改用 string,例如

     string[] n = { "1", "2", "3" };

    object[] o = n;

    歡迎參觀我的Blog.NET菜鳥自救會
    2011年4月26日 14:15
  • 这是个非常好的问题。这里涉及到有关协变 (Covariance) 的问题。

    所谓协变,就是指如果存在两个引用类型 A 和 B,如果 A > B (也就是 B 属于 A 的派生类),有开放类型 C<T>,且从封闭类型 C<B> 到 C<A> 的转换合法,那么就成类型 C<T> 支持协变。记作 C<out T> 或 C<T+>。

    在 .NET 2.0 和 3.5 中,数据可以“看成”是 Array<T>,其中 T 为数组的元素类型,.NET 2.0 / 3.5 支持数组的隐式协变,也就是说,如果存在下面的代码:

    public class A { }
    public class B { }

    A[] a;
    B[] b;
    a = b;

    是完全可以执行的。这里 A > B,A[] 和 B[] 可以看作是 Array<A> 和 Array<B>。(这里我不想讨论关于 CLR 对数组的处理,为了简化,就用 Array<T> 代替)。

    注意,因为协变只支持引用类型,因此,从值类型到引用类型的协变不支持。比如从 int[] 到 object[]。这就解释了您提出的上面的问题。

    进一步,如果 A < B,对于开放类型 C<T>,C<B> 到 C<A> 的转换合法,那么这个就叫逆变 (contravariance),记作 C<in T> 或者 C<T->。

    协变和逆变在 C# 4.0 的接口和委托中适用。对于其他类型,如数组以及部分委托,仍使用 C# 2.0 / 3.5 的隐式协变。

    要了解更多的协变/逆变的信息,可以参考我写的 PPT,http://www.markzhou.com/blog/page/Tech-Talk.aspx,然后下载 201003 的 PPT 或者代码。

    Series Number Presenter Topic PowerPoint Presentation Video Source Code
    201020 Mark Zhou ASP.NET MVC, Part 4 Download Download
    201019 Mark Zhou ASP.NET MVC, Part 3 Download Download
    201017 Mark Zhou ASP.NET MVC, Part 2
    201015 Mark Zhou ASP.NET MVC, Part 1 Download
    201008 Mark Zhou C#: Generics Download Download
    201006 Mark Zhou C#: Inside Operator Overloading Download
    201005 Mark Zhou C#: Operator Overloading Download Download
    201003 Mark Zhou C#: Covariance and contravariance Download Download

    Mark Zhou
    2011年4月26日 16:57

全部回复

  • 没人回复?
    steve
    2011年4月23日 1:43
  • 移至C#论坛寻求更好的支持
    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月26日 10:38
  • int 没有继承Object类


    胡超
    2011年4月26日 11:20
  • 您好

    int 無法轉為 object,您可以改用 string,例如

     string[] n = { "1", "2", "3" };

    object[] o = n;

    歡迎參觀我的Blog.NET菜鳥自救會
    2011年4月26日 14:15
  • 您好

    int 無法轉為 object,您可以改用 string,例如

     string[] n = { "1", "2", "3" };

    object[] o = n;

    歡迎參觀我的Blog.NET菜鳥自救會

    string继承object,这样是可以的。
    胡超
    2011年4月26日 15:54
  • 这是个非常好的问题。这里涉及到有关协变 (Covariance) 的问题。

    所谓协变,就是指如果存在两个引用类型 A 和 B,如果 A > B (也就是 B 属于 A 的派生类),有开放类型 C<T>,且从封闭类型 C<B> 到 C<A> 的转换合法,那么就成类型 C<T> 支持协变。记作 C<out T> 或 C<T+>。

    在 .NET 2.0 和 3.5 中,数据可以“看成”是 Array<T>,其中 T 为数组的元素类型,.NET 2.0 / 3.5 支持数组的隐式协变,也就是说,如果存在下面的代码:

    public class A { }
    public class B { }

    A[] a;
    B[] b;
    a = b;

    是完全可以执行的。这里 A > B,A[] 和 B[] 可以看作是 Array<A> 和 Array<B>。(这里我不想讨论关于 CLR 对数组的处理,为了简化,就用 Array<T> 代替)。

    注意,因为协变只支持引用类型,因此,从值类型到引用类型的协变不支持。比如从 int[] 到 object[]。这就解释了您提出的上面的问题。

    进一步,如果 A < B,对于开放类型 C<T>,C<B> 到 C<A> 的转换合法,那么这个就叫逆变 (contravariance),记作 C<in T> 或者 C<T->。

    协变和逆变在 C# 4.0 的接口和委托中适用。对于其他类型,如数组以及部分委托,仍使用 C# 2.0 / 3.5 的隐式协变。

    要了解更多的协变/逆变的信息,可以参考我写的 PPT,http://www.markzhou.com/blog/page/Tech-Talk.aspx,然后下载 201003 的 PPT 或者代码。

    Series Number Presenter Topic PowerPoint Presentation Video Source Code
    201020 Mark Zhou ASP.NET MVC, Part 4 Download Download
    201019 Mark Zhou ASP.NET MVC, Part 3 Download Download
    201017 Mark Zhou ASP.NET MVC, Part 2
    201015 Mark Zhou ASP.NET MVC, Part 1 Download
    201008 Mark Zhou C#: Generics Download Download
    201006 Mark Zhou C#: Inside Operator Overloading Download
    201005 Mark Zhou C#: Operator Overloading Download Download
    201003 Mark Zhou C#: Covariance and contravariance Download Download

    Mark Zhou
    2011年4月26日 16:57