是否可以使用以下内容:
class C
{
public Foo Foos[int i]
{
...
}
public Bar Bars[int i]
{
...
}
}
如果没有,那么我可以通过哪些方式实现这一目标?我知道我可以创建名为getFoo(int i)和getBar(int i)的函数,但我希望用属性来做这个。
答案 0 :(得分:16)
不在C#中,没有。
但是,您始终可以从属性返回集合,如下所示:
public IList<Foo> Foos
{
get { return ...; }
}
public IList<Bar> Bars
{
get { return ...; }
}
的IList&LT; T&GT;有一个索引器,所以你可以写下以下内容:
C whatever = new C();
Foo myFoo = whatever.Foos[13];
在“返回...;”行上你可以返回任何实现IList&lt; T&gt;的东西,但是你可以在你的集合周围返回一个只读包装器,参见AsReadOnly()方法。
答案 1 :(得分:16)
这来自C#3.0规范
“重载索引器允许类,结构或接口声明多个索引器,前提是它们的签名在该类,结构或接口中是唯一的。”
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);
}
}
}
答案 2 :(得分:5)
有一种方法..如果你定义了两种新类型,让编译器区分这两种不同的签名......
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;
}
然后打电话给你,你必须写:
Employee Bob = MyEmployeeCollection[new EmployeeID(34)];
如果你写了一个隐式转换运算符:
public static implicit operator EmployeeID(int x)
{ return new EmployeeID(x); }
然后你甚至不必这样做才能使用它,你可以写:
Employee Bob = MyEmployeeCollection[34];
即使两个索引器返回不同的类型,同样的事情也适用...
答案 3 :(得分:4)
尝试使用我的IndexProperty类在同一个类中启用multiple indexers
http://www.codeproject.com/Tips/319825/Multiple-Indexers-in-Csharp
答案 4 :(得分:3)
如果你想做这样的事情:
var myClass = new MyClass();
Console.WriteLine(myClass.Foos[0]);
Console.WriteLine(myClass.Bars[0]);
然后你需要在Foo和Bar类本身定义索引器 - 即将所有Foo对象放在Foos中,并使Foos成为支持直接索引的类型实例。
演示使用数组作为成员属性(因为它们已经支持索引器):
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; } }
}
允许你说:
C myThing = new C();
Console.WriteLine(myThing.Foos[1]);
Console.WriteLine(myThing.Bars[2]);
答案 5 :(得分:1)
我相信接受的答案是错误的。如果您将使用显式接口实现是可能的:
class C
{
public IFooProvider Foos => this;
public IBarProvider Bars => this;
Foo IFooProvider.this[int i]
{
...
}
Bar IBarProvider.this[int i]
{
...
}
public interface IFooProvider
{
Foo this[int i] { get; set; }
}
public interface IBarProvider
{
Bar this[int i] { get; set; }
}
}
然后您可以完全按照自己的意愿使用它:
C c;
c.Foos[1] = new Foo();
c.Bars[0] = new Bar();
答案 6 :(得分:0)
C#没有返回类型重载。如果输入参数不同,则可以定义多个索引器。
答案 7 :(得分:0)
不,你不能这样做。只有可以使其签名因返回类型而不同的方法才是转换运算符。索引器必须具有不同的输入参数类型才能使其编译。