在 C# 中实现不同的索引器 class
Implementation of different indexers within C# class
我想在我的 class 中添加不同的索引器实现:
特定集合
public class SpecificCollection<T> : ISpecificCollection <T>
{
public int this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public object this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public string this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public event void OnAddElement;
public event void OnRemoveElement;
public void AddNewElement(T element)
{
throw new NotImplementedException();
}
public void DeleteElement(int index)
{
throw new NotImplementedException();
}
public int Count
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
StudentSpecificCollection
public class StudentSpecificCollection : SpecificCollection<Student>
{
private string[] arrName;
private int[] arrAge;
private object[] arrStudent ;
public int ISpecificCollectionIndexers<Student>.this[int index]
{
get
{
return arrAge[index];
}
set
{
arrAge[index] = value;
}
}
object ISpecificCollectionIndexers<Student>.this[int index]
{
get
{
return arrStudent[index];
}
set
{
arrStudent[index] = value;
}
}
string ISpecificCollectionIndexers<Student>.this[int index]
{
get
{
return arrName[index];
}
set
{
arrName[index] = value;
}
}
public event void OnAddElement;
public event void OnRemoveElement;
public void AddNewElement(Student element)
{
object objStudent = arrStudent.Where(x => x != null).LastOrDefault();
int index = (objStudent == null) ? 0 : Array.IndexOf(arrStudent, objStudent);
arrName[index] = element.Name ;
arrAge[index] = element.Age;
arrStudent[index] = element;
}
public void DeleteElement(int index)
{
if (index > Count - 1) return;
arrName[index] = null;
arrAge[index] = -1;
arrStudent[index] = null;
}
public int Count
{
get
{
return arrName.Where(x=>x !=null).Count();
}
set
{
}
}
public StudentSpecificCollection()
{
arrName = new string[100];
arrAge = new int[100];
arrStudent = new object[100];
}
}
所以我需要知道:
- 如何使用不同的索引器实现?
- 在此 class 中实施不同类型索引的最佳做法是什么?
- 在哪些情况下自定义索引比使用不同的 C# 集合更好?
与 一样,return 类型不是方法签名的一部分。所以你不能像你的代码中那样做。
您可以使用显式接口提供多个索引器,如 中所示。
虽然代码没有任何意义。只需使用一个索引器并存储 return 学生对象,这样您就可以 string name = lstStudent[0].Name;
.
使用接口的显式实现,你可以做如下事情:
public interface IMyClass
{
object this[int index]
{
get; set;
}
}
public class MyClass : IMyClass
{
public string this[int index]
{
get
{
return "";
}
set
{
}
}
object IMyClass.this[int index]
{
get
{
return "";
}
set
{
}
}
}
因此实现两个具有相同签名的不同枚举器(其中签名 = type/number 输入参数)。请注意,您可以有多个接口,每个接口都有一个具有不同 return 类型的索引器,因此给定 x 个接口和一个 class,您可以有 x + 1 个具有相同签名的不同索引器。
现在...如果 Student
是 "real" class 而不是 object
,你可以用隐式转换做一些技巧(你不能做隐式转换 with/against object
class):
public class StudentSpecificCollection
{
private string[] arrName;
private int[] arrAge;
private object[] arrStudent;
public MyObject this[int index]
{
get
{
return new MyObject(this, index);
}
set
{
if (value.Type.HasFlag(MyObject.MyObjectType.Name))
{
arrName[index] = value;
}
if (value.Type.HasFlag(MyObject.MyObjectType.Age))
{
arrAge[index] = value;
}
if (value.Type.HasFlag(MyObject.MyObjectType.Student))
{
arrStudent[index] = value;
}
}
}
public class MyObject
{
[Flags]
public enum MyObjectType
{
Name = 1,
Age = 2,
Student = 4
}
public readonly MyObjectType Type;
public readonly string Name;
public readonly int Age;
public readonly object Student;
protected MyObject(string name)
{
Type = MyObjectType.Name;
Name = name;
}
protected MyObject(int age)
{
Type = MyObjectType.Age;
Age = age;
}
protected MyObject(object student)
{
Type = MyObjectType.Student;
Student = student;
}
public MyObject(StudentSpecificCollection obj, int ix)
{
Name = obj.arrName[ix];
Age = obj.arrAge[ix];
Student = obj.arrStudent[ix];
}
public static implicit operator string(MyObject obj)
{
if (!obj.Type.HasFlag(MyObjectType.Name))
{
throw new Exception();
}
return obj.Name;
}
public static implicit operator int(MyObject obj)
{
if (!obj.Type.HasFlag(MyObjectType.Age))
{
throw new Exception();
}
return obj.Age;
}
//public static implicit operator object(MyObject obj)
//{
// if (!obj.Type.HasFlag(MyObjectType.Student))
// {
// throw new Exception();
// }
// return obj.Student;
//}
public static implicit operator MyObject(string name)
{
return new MyObject(name);
}
public static implicit operator MyObject(int age)
{
return new MyObject(age);
}
//public static implicit operator MyObject(object student)
//{
// return new MyObject(student);
//}
}
}
(索引器 return 是一个 MyObject
class 然后可以隐式转换为 int
/string
)
然后用作
var obj = new StudentSpecificCollection();
// Load some students here
obj[0] = "Foo";
obj[0] = 25;
string name = obj[0];
int age = obj[0];
请注意,我不认为这是个好主意。但是你要求的。
我想在我的 class 中添加不同的索引器实现:
特定集合
public class SpecificCollection<T> : ISpecificCollection <T>
{
public int this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public object this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public string this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public event void OnAddElement;
public event void OnRemoveElement;
public void AddNewElement(T element)
{
throw new NotImplementedException();
}
public void DeleteElement(int index)
{
throw new NotImplementedException();
}
public int Count
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
StudentSpecificCollection
public class StudentSpecificCollection : SpecificCollection<Student>
{
private string[] arrName;
private int[] arrAge;
private object[] arrStudent ;
public int ISpecificCollectionIndexers<Student>.this[int index]
{
get
{
return arrAge[index];
}
set
{
arrAge[index] = value;
}
}
object ISpecificCollectionIndexers<Student>.this[int index]
{
get
{
return arrStudent[index];
}
set
{
arrStudent[index] = value;
}
}
string ISpecificCollectionIndexers<Student>.this[int index]
{
get
{
return arrName[index];
}
set
{
arrName[index] = value;
}
}
public event void OnAddElement;
public event void OnRemoveElement;
public void AddNewElement(Student element)
{
object objStudent = arrStudent.Where(x => x != null).LastOrDefault();
int index = (objStudent == null) ? 0 : Array.IndexOf(arrStudent, objStudent);
arrName[index] = element.Name ;
arrAge[index] = element.Age;
arrStudent[index] = element;
}
public void DeleteElement(int index)
{
if (index > Count - 1) return;
arrName[index] = null;
arrAge[index] = -1;
arrStudent[index] = null;
}
public int Count
{
get
{
return arrName.Where(x=>x !=null).Count();
}
set
{
}
}
public StudentSpecificCollection()
{
arrName = new string[100];
arrAge = new int[100];
arrStudent = new object[100];
}
}
所以我需要知道:
- 如何使用不同的索引器实现?
- 在此 class 中实施不同类型索引的最佳做法是什么?
- 在哪些情况下自定义索引比使用不同的 C# 集合更好?
与
您可以使用显式接口提供多个索引器,如
虽然代码没有任何意义。只需使用一个索引器并存储 return 学生对象,这样您就可以 string name = lstStudent[0].Name;
.
使用接口的显式实现,你可以做如下事情:
public interface IMyClass
{
object this[int index]
{
get; set;
}
}
public class MyClass : IMyClass
{
public string this[int index]
{
get
{
return "";
}
set
{
}
}
object IMyClass.this[int index]
{
get
{
return "";
}
set
{
}
}
}
因此实现两个具有相同签名的不同枚举器(其中签名 = type/number 输入参数)。请注意,您可以有多个接口,每个接口都有一个具有不同 return 类型的索引器,因此给定 x 个接口和一个 class,您可以有 x + 1 个具有相同签名的不同索引器。
现在...如果 Student
是 "real" class 而不是 object
,你可以用隐式转换做一些技巧(你不能做隐式转换 with/against object
class):
public class StudentSpecificCollection
{
private string[] arrName;
private int[] arrAge;
private object[] arrStudent;
public MyObject this[int index]
{
get
{
return new MyObject(this, index);
}
set
{
if (value.Type.HasFlag(MyObject.MyObjectType.Name))
{
arrName[index] = value;
}
if (value.Type.HasFlag(MyObject.MyObjectType.Age))
{
arrAge[index] = value;
}
if (value.Type.HasFlag(MyObject.MyObjectType.Student))
{
arrStudent[index] = value;
}
}
}
public class MyObject
{
[Flags]
public enum MyObjectType
{
Name = 1,
Age = 2,
Student = 4
}
public readonly MyObjectType Type;
public readonly string Name;
public readonly int Age;
public readonly object Student;
protected MyObject(string name)
{
Type = MyObjectType.Name;
Name = name;
}
protected MyObject(int age)
{
Type = MyObjectType.Age;
Age = age;
}
protected MyObject(object student)
{
Type = MyObjectType.Student;
Student = student;
}
public MyObject(StudentSpecificCollection obj, int ix)
{
Name = obj.arrName[ix];
Age = obj.arrAge[ix];
Student = obj.arrStudent[ix];
}
public static implicit operator string(MyObject obj)
{
if (!obj.Type.HasFlag(MyObjectType.Name))
{
throw new Exception();
}
return obj.Name;
}
public static implicit operator int(MyObject obj)
{
if (!obj.Type.HasFlag(MyObjectType.Age))
{
throw new Exception();
}
return obj.Age;
}
//public static implicit operator object(MyObject obj)
//{
// if (!obj.Type.HasFlag(MyObjectType.Student))
// {
// throw new Exception();
// }
// return obj.Student;
//}
public static implicit operator MyObject(string name)
{
return new MyObject(name);
}
public static implicit operator MyObject(int age)
{
return new MyObject(age);
}
//public static implicit operator MyObject(object student)
//{
// return new MyObject(student);
//}
}
}
(索引器 return 是一个 MyObject
class 然后可以隐式转换为 int
/string
)
然后用作
var obj = new StudentSpecificCollection();
// Load some students here
obj[0] = "Foo";
obj[0] = 25;
string name = obj[0];
int age = obj[0];
请注意,我不认为这是个好主意。但是你要求的。