C# 多个索引器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/431339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Multiple Indexers
提问by smack0007
Is it possible to have something like the following:
是否有可能有以下内容:
class C
{
public Foo Foos[int i]
{
...
}
public Bar Bars[int i]
{
...
}
}
If not, then are what are some of the ways I can achieve this? I know I could make functions called getFoo(int i) and getBar(int i) but I was hoping to do this with properties.
如果没有,那么我可以通过哪些方式实现这一目标?我知道我可以创建名为 getFoo(int i) 和 getBar(int i) 的函数,但我希望用属性来做到这一点。
采纳答案by smack0007
Not in C#, no.
不是在 C# 中,不是。
However, you can always return collections from properties, as follows:
但是,您始终可以从属性返回集合,如下所示:
public IList<Foo> Foos
{
get { return ...; }
}
public IList<Bar> Bars
{
get { return ...; }
}
IList<T> has an indexer, so you can write the following:
IList<T> 有一个索引器,因此您可以编写以下内容:
C whatever = new C();
Foo myFoo = whatever.Foos[13];
On the lines "return ...;" you can return whatever implements IList<T>, but you might what to return a read-only wrapper around your collection, see AsReadOnly() method.
在“返回...;”行上 您可以返回任何实现 IList<T> 的内容,但您可能会返回一个围绕您的集合的只读包装器,请参阅 AsReadOnly() 方法。
回答by Dylan Beattie
If you're trying to do something like this:
如果你试图做这样的事情:
var myClass = new MyClass();
Console.WriteLine(myClass.Foos[0]);
Console.WriteLine(myClass.Bars[0]);
then you need to define the indexers on the Foo and Bar classes themselves - i.e. put all the Foo objects inside Foos, and make Foos a type instance that supports indexing directly.
那么你需要在 Foo 和 Bar 类本身上定义索引器——即将所有 Foo 对象放在 Foos 中,并使 Foos 成为直接支持索引的类型实例。
To demonstrate using arrays for the member properties (since they already support indexers):
演示对成员属性使用数组(因为它们已经支持索引器):
public class C {
private string[] foos = new string[] { "foo1", "foo2", "foo3" };
private string[] bars = new string[] { "bar1", "bar2", "bar3" };
public string[] Foos { get { return foos; } }
public string[] Bars { get { return bars; } }
}
would allow you to say:
会让你说:
C myThing = new C();
Console.WriteLine(myThing.Foos[1]);
Console.WriteLine(myThing.Bars[2]);
回答by JoshBerke
C# doesn't have return type overloading. You can define multiple indexers if their input parameters are different.
C# 没有返回类型重载。如果输入参数不同,您可以定义多个索引器。
回答by Krzysztof Kozmic
No you cant do it. Only methods that can have their signatures differ only by return type are conversion operators. Indexers must have different input parameter types to get it to compile.
不,你不能这样做。只有可以使签名仅因返回类型不同而不同的方法才是转换运算符。索引器必须具有不同的输入参数类型才能编译。
回答by Charles Bretana
There IS a way.. if you define 2 new types to alow the compiler to distinguish the two different signatures...
有一种方法......如果你定义了 2 个新类型来让编译器区分这两种不同的签名......
public struct EmployeeId
{
public int val;
public EmployeeId(int employeeId) { val = employeeId; }
}
public struct HRId
{
public int val;
public HRId(int hrId) { val = hrId; }
}
public class Employee
{
public int EmployeeId;
public int HrId;
// other stuff
}
public class Employees: Collection<Employee>
{
public Employee this[EmployeeId employeeId]
{
get
{
foreach (Employee emp in this)
if (emp.EmployeeId == employeeId.val)
return emp;
return null;
}
}
public Employee this[HRId hrId]
{
get
{
foreach (Employee emp in this)
if (emp.HRId == hrId.val)
return emp;
return null;
}
}
// (or using new C#6+ "expression-body" syntax)
public Employee this[EmployeeId empId] =>
this.FirstorDefault(e=>e.EmployeeId == empId .val;
public Employee this[HRId hrId] =>
this.FirstorDefault(e=>e.EmployeeId == hrId.val;
}
Then to call it you would have to write:
然后调用它,你必须写:
Employee Bob = MyEmployeeCollection[new EmployeeID(34)];
And if you wrote an implicit conversion operator:
如果您编写了一个隐式转换运算符:
public static implicit operator EmployeeID(int x)
{ return new EmployeeID(x); }
then you wouldn't even have to do that to use it, you could just write:
那么你甚至不必这样做来使用它,你可以写:
Employee Bob = MyEmployeeCollection[34];
Same thing applies even if the two indexers return different types...
即使两个索引器返回不同的类型,同样的事情也适用......
回答by Jacob_J
This from C# 3.0 spec
这来自 C# 3.0 规范
"Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface."
“索引器的重载允许一个类、结构或接口声明多个索引器,前提是它们的签名在该类、结构或接口中是唯一的。”
public class MultiIndexer : List<string>
{
public string this[int i]
{
get{
return this[i];
}
}
public string this[string pValue]
{
get
{
//Just to demonstrate
return this.Find(x => x == pValue);
}
}
}
回答by Sion COhen
Try my IndexProperty class to enable multiple indexersin the same class
尝试使用我的 IndexProperty 类在同一类中启用多个索引器
http://www.codeproject.com/Tips/319825/Multiple-Indexers-in-Csharp
http://www.codeproject.com/Tips/319825/Multiple-Indexers-in-Csharp