gpt4 book ai didi

.net - 为什么.NET 中没有 IArray(T) 接口(interface)?

转载 作者:行者123 更新时间:2023-12-03 20:54:26 25 4
gpt4 key购买 nike

2011 年 1 月 6 日更新:

信不信由你,我继续把这个界面合并到an open source library I've started, Tao.NET .我wrote a blog post解释这个图书馆的 IArray<T>界面,它不仅解决了我最初在这个问题中提出的问题(一年前?!),而且还提供了 协变索引接口(interface) ,BCL 中非常缺乏(在我看来)的东西。

问题(简而言之):

我问为什么 .NET 有 IList<T> ,它实现了 ICollection<T>因此提供了修改列表的方法( AddRemove 等),但不提供任何中间接口(interface),例如 IArray<T>通过索引提供随机访问,无需任何列表修改。

编辑 2010 年 1 月 21 日美国东部时间下午 2:22:

在对 Jon Skeet 的原始回答的评论中(他质疑人们多久需要一份诸如 IArray<T> 之类的契约(Contract)),我提到了 KeysValues SortedList<TKey, TValues> 的属性类是IList<TKey>IList<Value> ,分别,乔恩回答说:

But in this case it's declared to be IList and you know to just use the indexers. . . . It's not hugely elegant, I agree - but it doesn't actually cause me any pain.



这是合理的,但我会说 它不会给您带来任何痛苦,因为您只知道自己做不到 .但是 原因 你知道 不是 从代码中可以清楚地看出;那是你有使用 SortedList<TKey, TValue> 的经验类(class)。

如果我这样做,Visual Studio 不会给我任何警告:
SortedList<string, int> mySortedList = new SortedList<string, int>();

// ...

IList<string> keys = mySortedList.Keys;
keys.Add("newkey");

根据 IList<string>,这是合法的.但是我们都知道,它会导致异常。

纪尧姆也提出了一个恰当的观点:

Well, the interfaces aren't perfect but a dev can check the IsReadOnly property before calling Add/Remove/Set...



同样,这是合理的, 但是 : 这不是让你觉得有点迂回吗?

假设我定义了一个接口(interface)如下:
public interface ICanWalkAndRun {
bool IsCapableOfRunning { get; }

void Walk();
void Run();
}

现在,还假设我已将实现此接口(interface)作为一种常见做法,但仅适用于它的 Walk方法;在很多情况下,我会选择设置 IsCapableOfRunningfalse并抛出 NotSupportedExceptionRun ...

然后我可能有一些看起来像这样的代码:
var walkerRunners = new Dictionary<string, ICanWalkAndRun>();

// ...

ICanWalkAndRun walkerRunner = walkerRunners["somekey"];

if (walkerRunner.IsCapableOfRunning) {
walkerRunner.Run();
} else {
walkerRunner.Walk();
}

我是疯了吗,还是这种破坏了一个名为 ICanWalkAndRun 的接口(interface)的目的? ?

原帖

我发现在 .NET 中,当我设计一个具有通过索引提供随机访问的集合属性(或返回索引集合的方法等)的类时,这是非常奇怪的, 但不应或不能通过添加/删除项目进行修改 ,如果我想以 OOP 方式“做正确的事”并提供一个接口(interface),以便我可以在不破坏 API 的情况下更改内部实现,我必须使用 IList<T> .

标准方法似乎是采用 IList<T> 的一些实现。明确定义方法 Add , Insert等 - 通常通过执行以下操作:
private List<T> _items;
public IList<T> Items {
get { return _items.AsReadOnly(); }
}

但我有点讨厌这个。如果另一个开发人员正在使用我的类,并且我的类具有类型 IList<T> 的属性, 和 接口(interface)的整个想法是:“这些是一些可用的属性和方法” ,我为什么要扔 NotSupportedException (或无论如何)当他/她试图做一些根据界面应该完全合法的事情时?

我觉得实现一个接口(interface)并明确定义它的一些成员就像开一家餐厅并在菜单上放一些项目——也许是在菜单的某个模糊的、容易错过的部分,但仍然在菜单上——根本不可用。

似乎应该有类似 IArray<T> 的东西通过索引提供非常基本的随机访问的接口(interface),但没有添加/删除,如下所示:
public interface IArray<T> {
int Length { get; }
T this[int index] { get; }
}

然后 IList<T>可以实现 ICollection<T>IArray<T>并添加其 IndexOf , InsertRemoveAt方法。

当然,我总是可以只编写这个接口(interface)并自己使用它,但这对所有没有实现它的预先存在的 .NET 类没有帮助。 (是的,我知道我可以写一个包装器,它接受任何 IList<T> 并吐出一个 IArray<T> ,但是......真的吗?)

有没有人知道为什么System.Collections.Generic 中的接口(interface)?是这样设计的?我错过了什么吗?是否有一个令人信服的论点反对我所说的关于明确定义 IList<T> 成员的方法的问题? ?

我并不是想听起来自大,好像我比设计 .NET 类和接口(interface)的人更了解;它只是没有意义 给我 .但我已经准备好承认有很多我可能没有考虑到的。

最佳答案

设计问题并不总是非黑即白的。

一方面是针对每种情况的精确接口(interface),这使得实际实现接口(interface)的整个过程变得非常痛苦。

另一个是少数(er)多用途接口(interface),它们并不总是完全被实现者支持,但使许多事情变得更容易,例如传递相似但不会获得“精确接口(interface)”设计中分配的相同接口(interface)的实例.

所以BCL设计师选择了第二种方式。有时我也希望接口(interface)少一点多用途,特别是对于集合和 C#4 接口(interface)协/逆变特性(不能应用于大多数集合接口(interface),除了 IEnumerable<>,因为它们包含两个协以及逆变部分)。

此外,令人遗憾的是,诸如字符串和原始类型之类的基类不支持某些接口(interface),例如 ICharStream(对于字符串,可用于正则表达式等以允许使用除 string 实例之外的其他来源进行模式匹配)或 IArithmetic 用于数字基元,以便通用数学成为可能。但我想所有框架都有一些弱点。

关于.net - 为什么.NET 中没有 IArray(T) 接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2110440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com