【发布时间】:2018-02-13 17:25:01
【问题描述】:
我不太确定我是否理解什么 OOP 原则阻止我使用类型 B 中的方法,而我将类型 A 转换为。
具体例子:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
string[] week = new string[] { "Monday", "Tuesday", "wednesday", "Saturday", "Sunday"};
ICollection<string> coll = (ICollection<string>)week;
coll.Add("SlaveDay"); // this throws an error
ICollection<string> coll2 = new List<string>() { "Monday", "Tuesday", "wednesday", "Saturday", "Sunday" };
coll2.Add("SlaveDay"); // this works
}
}
当然,数组是固定大小的,所以我明白为什么不能添加任何新元素周(类型为string[] 或字符串数组)。
但是,在我明确地将其转换为 ICollection<string>(顺便说一下,它与 IReadableCollection<string> 不同)之后,我本来希望添加一个新元素来工作。
https://msdn.microsoft.com/en-us/library/system.array.aspx#Remarks
我从这里发现
数组类显式实现了IList.Add(Object) 并且调用此方法总是会引发 NotSupportedException 异常。
这就是为什么第一次调用会抛出错误的解释吗?
如果是这样,是否可以假定Add 是Array 类中的一个方法,它覆盖了IList 中的Add 方法? (覆盖关键字而不是新关键字)
例如如果它是一个新方法而不是覆盖,那行就不会抛出错误,是吗?
其次,这种情况的原因是:在预期是通常可修改的集合ICollection<T>(而不是IReadableCollection<T>)中,我们有一个名为IsReadOnly的属性?
感谢您的澄清。
【问题讨论】:
-
你怎么能期望它起作用?它会做什么?铸造不会改变任何东西。它仍然是一个数组;你只是看待它的方式不同。
-
同意 SLaks。我认为您混淆了 Conversion 和 Cast,而 Conversion 通常从一种类型复制到另一种类型。
-
您将转换和转换混为一谈,这无疑是由于某些转换也执行转换的事实。很不幸。但简单的事实是这里没有发生转换,这就是 Add 失败的原因。
-
Anthony Pegram,很有趣,有些演员也执行转换?你能详细说明一下吗?谢谢大家!
-
@hhdr103 从一个类到另一个类的自定义转换使用熟悉的“(Cast)”语法。原语的转换也是如此 (
int x = (int)some decimal;)。当然,这些是例外,而不是规则。