如何使用C#泛型代替字符串和byte []

Noa*_*oah 4 c# generics

是否可以使用C#generics将这4个例程替换为1个?

int memcmp (string a, string b){...}
int memcmp (string a, byte[] b){...}
int memcmp (byte[]a,  string b){...}
int memcmp (byte[]a,  byte[] b){...}
Run Code Online (Sandbox Code Playgroud)

我尝试了很多变化,但无法准确确定要使用的内容......

例如...

int memcmp<A, B>( A a, B b) 
{
  if ( a.Length < b.Length ) return 1;
  for ( int i = 0 ; i < a.Length ; i++ )
  {
    if ( a[i] != b[i] ) return ( a[i] < b[i] ) ? -1 : 1;
  }
 }
Run Code Online (Sandbox Code Playgroud)

出现以下错误:

  • 'A'不包含'Length'的定义
  • 无法将带有[]的索引应用于类型为"A"的表达式

讨论这个的好参考在哪里?

**注意:**我不是在寻找如何比较字符串和字节的解决方案,而是寻求使用"概念验证"问题来理解泛型如何在C#中工作

Tin*_*ter 6

您理想的解决方案将具有以下特征:

int memcmp<T>( T a, T b ) where T : IHasLengthAndIndexer
Run Code Online (Sandbox Code Playgroud)

其中IHasLengthAndIndexer定义为:

public interface IHasLengthAndIndexer
{
    int Length { get; }
    byte this[ int index ] { get; }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以传入任何类型,假设类型实现 IHasLengthAndIndexer

但是你不能改变的接口byte[],并string因此该方案将不会取代你的四种方法.

但是,您可以创建自己的类,该类具有隐式运算符byte[],string并创建一个比较该类实例的方法,但不使用泛型.

  • 如果这是lolcode,我建议将"IHasLengthAndIndexer"重命名为"ICanHasLengthAndIndexer".;) (3认同)

Pav*_*aev 5

您不能在泛型类型参数的值上调用成员,除非您具有明确要求作为类型参数传递的任何类型具有此类成员的类型约束.这是通过将它们约束到特定的界面来完成的(你不能只说,"我想要任何A东西都可以Length).

在你的情况下,没有好办法做到这一点,因为在string和数组之间没有提供Length(或Count,或类似)的通用接口.数组实现IList<T>,但遗憾的string是没有.两者都实现IEnumerable<T>,但这没有任何方法可以快速检索计数(您可以使用Enumerable.Count,但它实际上将迭代整个字符串以计算字符数).