我想实现一个集合,其项目需要进行空虚测试.在引用类型的情况下,将测试为null.对于值类型,必须实现空测试,并且可能选择表示空白的特定值.
我的T的一般集合应该是两个值和参考类型值可用(意味着Coll<MyCalss>和Coll<int>都应该是可能的).但我必须以不同方式测试引用和值类型.
拥有一个实现IsEmpty()方法的接口,从我的泛型类型中排除这个逻辑,这不是很好吗?但是,当然,这个IsEmpty()方法不能是成员函数:它无法在空对象上调用.
我找到的一个解决方法是将收集项目存储为对象,而不是Ts,但它让我头疼(围绕拳击和强类型).在旧的C++中没有问题:-)
下面的代码演示了我想要实现的目标:
using System;
using System.Collections.Generic;
namespace StaticMethodInInterfaceDemo
{
public interface IEmpty<T>
{
static T GetEmpty(); // or static T Empty;
static bool IsEmpty(T ItemToTest);
}
public class Coll<T> where T : IEmpty<T>
{
protected T[] Items;
protected int Count;
public Coll(int Capacity)
{
this.Items = new T[Capacity];
this.Count = 0;
}
public void Remove(T ItemToRemove)
{
int Index = Find(ItemToRemove);
// Problem spot 1: This throws a compiler error: "Cannot convert null to type parameter 'T'
// because it could be a non-nullable value type. Consider using 'default(T)' instead."
this.Items[Index] = null;
// To overcome, I'd like to write this:
this.Items[Index] = T.Empty; // or T.GetEmpty(), whatever.
this.Count--;
}
public T[] ToArray()
{
T[] ret = new T[this.Count];
int TargetIndex = 0;
for(int Index = 0; Index < this.Items.GetLength(0); Index++)
{
T Item = this.Items[Index];
// Problem spot 2: This test is not correct for value types.
if (Item != null)
ret[TargetIndex++] = Item;
// I'd like to do this:
if (!T.IsEmpty(Item))
ret[TargetIndex++] = Item;
}
return ret;
}
protected int Find(T ItemToFind)
{
return 1; // Not implemented in the sample.
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以为名为IsEmpty的接口创建扩展方法.然后,您可以首先测试此扩展方法中的'this'参数是否为null.
所以你可以在对实现你的接口的类型的任何引用上调用IsEmpty方法,而不是关于它是否为null.