有人能把文档中的这句话翻译成人类语言吗:
索引器的类型及其参数的类型必须至少与索引器本身一样可访问
- 那么,如果"索引器的类型">是int或float,那么如何访问int和float?"索引器的类型">和"索引器本身">之间有什么区别
- 那么"parameters">这些值是否在方括号内?那么什么是形式参数
- 再说一遍,"参数类型">如何访问
- 然后是整句话的意思
索引器由两种不同的类型组成:方括号中传递的索引类型和与该索引相关的元素类型。您似乎认为索引在所有方面都是int
。这是没有任何限制的,它可以是任何任意类型:
public class MyClass
{
public ThirdClass this[IndexClass i] { get { ... }; set { ... } }
}
这假设ThirdClass
和IndexClass
都是可访问的。例如,如果IndexClass
是internal
类,那么上面的代码肯定不会编译,因为属性(在我们的例子中是索引器)是public
。
这对索引器来说一点也不特别。想象一下任何常用的方法:
public ThirdClass(IndexClass i)
{
...
}
这里适用相同的访问规则:ThirdClass
和IndexClass
必须具有至少与公开这些类型的成员相同的访问能力(或更高的访问能力)。
简单地说,当使用特定的访问修饰符时,不能使Indexer、Properties或Methods包含不可访问的类型。
Public使这些东西在其他库中可见,并且公开返回或接受类型为internal
的Indexer是没有意义的,因为它在其他库中将不可用(因为您不能使用这些类型)。如果您使索引器为internal
,则不能使其返回或采用private
类型,因为它在库中的其他类中再次不可用。
但您应该知道,索引器的可访问性取决于封闭类型。
考虑这个例子:
public class Bar { }
public class Foo { }
public class IndexerClass
{
public Bar this[Foo param]
{
get { return null; }
}
}
所有内容都是public
,并且应该在其他库中可见,您不能将Bar
或Foo
设为internal
,因为它们对其他库不可见。编译器不允许你编译这个。如果要使Bar
或Foo
成为internal
,则必须降低索引器的可访问性,因此可以使索引器本身成为internal
,也可以使类IndexerClass
成为internal
。
internal class Foo { }
internal class IndexerClass
{
public Bar this[Foo param]
{
get { return null; }
}
}
文档所指的是访问修饰符。
这告诉你的是,你使用的两种类型,一种是索引器返回的类型,另一种是用作索引参数的类型,需要具有与索引器本身相同的可访问性级别。
考虑一下:
public class SomeClass
{
public IndexerResult this[int index] // Indexer declaration
{
// get and set accessors
}
}
internal class IndexerResult
{
//Some code
}
然后你试试这个:
SomeClass obj = new SomeClass();
var value = obj[0];
如果你试图编译,你会得到一个错误:
可访问性不一致:索引器返回类型"IndexerResult"的可访问性低于索引器"SomeClassthis[int]">
原因显而易见,并在消息中进行了解释。不能让public
索引器公开internal
类(IndexerResult
)。
参数index
也是如此。考虑一下如果我们翻转类型会发生什么:
public int this[IndexerResult index] // Indexer declaration
{
// get and set accessors
}
这一次,您正试图使用一个比该方法更难访问的类型。如果类型是内部类型,我如何创建IndexerResult
的实例以传递给索引器?
现在踢球者来了。考虑一下当你使用一个接口时会发生什么:
public class SomeClass
{
public IIndexerResult this[int index]
{
get { return new IndexerResult(); } //This is perfectly fine!
}
}
internal class IndexerResult : IIndexerResult
{
//Some code
}
public interface IIndexerResult
{
}
这将在没有问题的情况下编译,并且您将能够在外部使用internal
类IndexerResult
。这是因为实现的细节现在隐藏在接口后面,所以您不知道实际的对象。除了您选择公开的内容(由接口表示)之外,没有任何内容是"公开的"。