为什么会出现在.NET中没有IArray(T)接口? [英] Why is there no IArray(T) interface in .NET?

查看:214
本文介绍了为什么会出现在.NET中没有IArray(T)接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不管你信不信,我继续将这一界面到一个开源库我已经开始,Tao.NET 。我wrote博客文章解释这个库的 IArray< T> 接口,这不仅解决了我原来提出的问题,这个问题(一年前?!),而且还提供了协索引接口,在BCL东西是非常缺乏的(在我看来)。

Believe it or not, I went ahead and incorporated this interface into an open source library I've started, Tao.NET. I wrote a blog post explaining this library's IArray<T> interface, which not only addresses the issues I originally raised in this question (a year ago?!) but also provides a covariant indexed interface, something that's sorely lacking (in my opinion) in the BCL.

我问为什么.NET已的IList&LT; T&GT; ,它实现的ICollection&LT; T&GT; ,因此提供了一些方法修改列表(添加删除等),但不提供任何介于两者之间的接口,例如为 IArray&LT; T&GT; 以提供索引,没有任何修改列表随机访问

I asked why .NET has IList<T>, which implements ICollection<T> and therefore provides methods to modify the list (Add, Remove, etc.), but doesn't offer any in-between interface such as IArray<T> to provide random access by index without any list modification.

在一个注释乔恩斯基特的原来的答复(其中他质疑人会怎么经常有任何需要一个合同,如 IArray&LT; T&GT; ),我提到,在排序列表&LT的性能; TKEY的,TValues​​&GT; 类是的IList&LT; TKEY的&GT; 的IList&LT;价值&GT; ,分别到乔恩说:

In a comment to Jon Skeet's original answer (in which he questioned how often one would have any need for a contract such as IArray<T>), I mentioned that the Keys and Values properties of the SortedList<TKey, TValues> class are IList<TKey> and IList<Value>, respectively, to which Jon replied:

但是,在这种情况下,它宣布为   IList的,你知道只使用   索引。 。 。 。这不是巨大   优雅的,我同意 - 但事实并非如此   其实导致我任何痛苦。

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.

这是合理的,但我会说是的它不会对你有疼痛的反应,因为你刚才的知道的你不能做到这一点。但在的原因你知道的不是,它是从code清晰的;那就是你有经验的排序列表&LT; TKEY的,TValue&GT;

This is reasonable, but I would respond by saying that it doesn't cause you any pain because you just know you can't do it. But the reason you know isn't that it's clear from the code; it's that you have experience with the SortedList<TKey, TValue> class.

Visual Studio是不会给我任何警告,如果我这样做:

Visual Studio isn't going to give me any warnings if I do this:

SortedList<string, int> mySortedList = new SortedList<string, int>();

// ...

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

这是合法的,根据的IList&LT;字符串&GT; 。但我们都知道,这将导致异常。

It's legal, according to IList<string>. But we all know, it's going to cause an exception.

纪尧姆作出一个恰当的点,以及:

Guillaume made an apt point as well:

好了,接口是不完美   但开发可以检查的IsReadOnly   前物业打电话   添加/删除/设置...

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

再次,这是合理的,:?这难道不是让你觉得有点迂回

Again, this is reasonable, BUT: does this not strike you as a bit circuitous?

假设我定义的界面如下:

Suppose I defined an interface as follows:

public interface ICanWalkAndRun {
    bool IsCapableOfRunning { get; }

    void Walk();
    void Run();
}

现在,假设还有我做这一种常见的做法来实现这个接口,但仅限于它的方法;在很多情况下,我会选择来设置 IsCapableOfRunning 并抛出一个 NotSupportedException异常运行 ...

Now, suppose as well that I made it a common practice to implement this interface, but only for its Walk method; in many cases, I would opt to set IsCapableOfRunning to false and throw a NotSupportedException on Run...

然后,我可能有一些code,它是这样的:

Then I might have some code that looked like this:

var walkerRunners = new Dictionary<string, ICanWalkAndRun>();

// ...

ICanWalkAndRun walkerRunner = walkerRunners["somekey"];

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

我疯了,或者是这种被称为打败接口的目的 ICanWalkAndRun

我觉得很奇怪,在.NET中,当我设计一个类,它提供通过索引随机访问(或返回一个索引集合的方法等),的集合财产,但不应该或无法通过添加/删除项修改,如果我想做正确的事OOP明智的,并提供一个接口,这样我可以改变内部实现不破坏API,我必须去与的IList&LT; T&GT;

I find it very peculiar that in .NET, when I am designing a class with a collection property that provides random access by index (or a method that returns an indexed collection, etc.), but should not or cannot be modified by adding/removing items, and if I want to "do the right thing" OOP-wise and provide an interface so that I can change the internal implementation without breaking the API, I have to go with IList<T>.

标准的做法,似乎是去一些实施的IList&LT的; T&GT; 明确定义方法添加插入等 - 通常是通过做一些这样的:

The standard approach, it seems, is to go with some implementation of IList<T> that explicitly defines the methods Add, Insert, etc. -- typically by doing something like:

private List<T> _items;
public IList<T> Items {
    get { return _items.AsReadOnly(); }
}

那种

不过,我讨厌这一点。如果其他开发人员正在使用我的课,我的类有型的IList℃的财产; T&GT; 接口的整体思路是:这些都是一些可用的属性和方法,我为什么要抛出一个 NotSupportedException异常(或任何情况而定)时,他/她试图做一些事情,根据接口,应该是完全合法的吗?

But I kind of hate this. If another developer is using my class, and my class has a property of type IList<T>, and the whole idea of an interface is: "these are some available properties and methods", why should I throw a NotSupportedException (or whatever the case may be) when he/she tries to do something that, according to the interface, should be completely legal?

我觉得自己实现一个接口,并明确界定它的一些成员是一样的菜单上开一家餐馆,并把一些项目 - 在一些不起眼,容易错过的部分的的可能菜单,但是的的菜单仍然 - 这是根本不会用

I feel like implementing an interface and explicitly defining some of its members is like opening a restaurant and putting some items on the menu -- perhaps in some obscure, easy-to-miss part of the menu, but on the menu nonetheless -- that are simply never available.

这似乎也应该是这样的一个 IArray&LT; T&GT; 接口,提供了指数非常基本的随机访问,但没有添加/删除,如下所示:

It seems there ought to be something like an IArray<T> interface that provides very basic random access by index, but no adding/removing, like the following:

public interface IArray<T> {
    int Length { get; }
    T this[int index] { get; }
}

然后的IList&LT; T&GT; 可以实施的ICollection&LT; T&GT; IArray&LT; T&GT; 并添加了的IndexOf 插入 RemoveAt 的方法。

And then IList<T> could implement ICollection<T> and IArray<T> and add its IndexOf, Insert and RemoveAt methods.

当然,我可能永远只是写的界面和使用它自己,但这并不能帮助所有的pre-现有的.NET没有实现它的类。 (是的,我知道我可以写一个包装,采取任何的IList&LT; T&GT; 键,吐出一个 IArray&LT; T&GT; ,但......严重?)

Of course, I could always just write this interface and use it myself, but that doesn't help with all the pre-existing .NET classes that don't implement it. (And yes, I know I could write a wrapper that takes any IList<T> and spits out an IArray<T>, but ... seriously?)

没有人有任何见解,为什么在 System.Collections.Generic 的接口设计这条路?我失去了一些东西?何乐而不为的什么,我说我的问题与的IList&LT的明确定义成员方法一个令人信服的理由的; T&GT;

Does anyone have any insight into why the interfaces in System.Collections.Generic were designed this way? Am I missing something? Is there a compelling argument against what I'm saying about my issues with the approach of explicitly defining members of IList<T>?

我并不是要健全自大,因为如果我知道不是谁设计的.NET类和接口的人好;它只是没有任何意义的。但我准备好承认有很多我可能还没有考虑。

I'm not trying to sound cocky, as if I know better than the people who designed the .NET classes and interfaces; it just doesn't make sense to me. But I'm ready to acknowledge there's plenty I probably haven't taken into consideration.

推荐答案

设计问题并不总是黑色和白色。

Design questions are not always black and white.

一边是各种情况,这使得实际执行的接口一个真正的痛苦全过程的精确接口。

One side is exact interfaces for each situation, which makes the whole process of actually implementing interfaces a real pain.

另一种是少数(ER)的多功能接口,它并不总是完全实现者的支持,但让很多事情变得更容易,比如传球实例都围绕相似,但不会带来精确分配相同的接口界面设计。

The other is few(er) multi-purpose interfaces which aren't always fully supported by the implementor but make many things easier, such as passing instances around which are similar but would not get the same interfaces assigned in the "exact interface" design.

因此​​,BCL设计师选择了去了第二种方式。有时我也在想,接口是有点少多用,尤其是对收藏和C#4接口合作/逆变功能(不能应用于大多数集合接口escept为IEnumerable的&LT;>,因为它们包含两个合作以及逆变份)。

So the BCL designers chose to go the second way. Sometimes I also wish that interfaces were a little less multi-purpose, especially for the collections and with the C#4 interface co-/contravariance features (which cannot be applied to most collection interfaces escept for IEnumerable<> because they contain both co- as well as contravariant parts).

此外,这是一个耻辱的基类,如字符串和原始类型不支持某些接口,如ICharStream(字符串,它可用于正则表达式等,允许使用其他来源的比模式匹配)或IArithmetic为数字基元字符串情况下,让一般的数学将是可能的。但我想,所有的框架有一些不足之处。

Also, it's a shame that the base classes such as string and the primitive types do not support some interfaces such as ICharStream (for strings, which could be used for regex etc. to allow using other sources than string instances for pattern matching) or IArithmetic for numeric primitives, so that generic math would be possible. But I guess that all frameworks have some weak points.

这篇关于为什么会出现在.NET中没有IArray(T)接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆