【问题标题】:Generic TypeCode Type Checking?通用 TypeCode 类型检查?
【发布时间】:2015-06-15 05:46:44
【问题描述】:

我应该避免使用泛型进行类型检查吗?不使用传统的类型检查比较(myvar is int),而是使用类型的类型码。

使用泛型和类型检查,您可以创建一个不带参数的方法,支持常规重载方法的任务。这是无参数方法的问题,它们不能重载。

// "Buffer" is the byte[] while "Peek" is the read/write position. Then Align" is the alignment size in bytes of the buffer.
public type Read<type>() {
    switch( Type.GetTypeCode( typeof( type ) ) ) {
        case System.TypeCode.Boolean:
            bool bool_val = ( Buff[ Peek ] > 0 );
            Peek = ( ++Peek + ( Align - 1 ) ) & ~( Align - 1 );
            return (type)(object)bool_val;
        case System.TypeCode.Byte:
            byte byte_val = Buff[ Peek ];
            Peek = ( ++Peek + ( Align - 1 ) ) & ~( Align - 1 );
            return (type)(object)byte_val;
        case TypeCode.Ushort:
            ushort ushort_val = (ushort)( Buff[ Peek ] | ( Buff[ Peek + 1 ] << 8 ) );
            Peek += 2;
            Peek = ( Peek + ( Align - 1 ) ) & ~( Align - 1 );
            return (type)(object)ushort_val;
        break;
        ...
    }
}

这似乎是使用无参数方法实现某种形式的重载的唯一方法。这被认为是不好的做法吗?

【问题讨论】:

  • 某事是好是坏的做法通常与上下文相关。您能否提供更多关于您想要实现的目标的详细信息?
  • 好点。我有一个正在为网络系统编写的缓冲区类。我需要几种类型的读/写方法。然而,这对于读取方法来说并不容易,因为它们不能被重载。这迫使我要么使用通用类型检查,要么使用多种个性化方法——从设计的角度来看,这也很糟糕。但是,您可以将其应用于大多数需要通用控制的单一多功能类型方法的情况。
  • 您能否分别举例说明BooleanByte 的情况?就目前而言,我什至不认为有必要使这个方法通用(而不是将Type 作为常规参数传递)。如果该方法不需要是通用的——而只是简单地用作硬编码的特殊情况的调用点——那么不,做你正在做的事情并不是一个坏习惯(因为没有其他方法来实现它)。但是,正如我所说,方法主体中的更多细节会让您更容易看到您的想法。
  • 完成,更改了 OP。是的,我必须硬编码专门案例,因为从缓冲区中读取不同的类型需要不同的案例。
  • 我试图为结构的通用方法提供一个大纲。如果您还需要处理字符串,那么不幸的是,您肯定必须提供明确的特化。

标签: c# generics


【解决方案1】:

您可以通过以下方式使您的代码通用:

var size = Marshal.SizeOf(typeof(T));
var subBuffer = new byte[size];
Array.Copy(Buff, Peek, subBuffer, 0, size);
var handle = GCHandle.Alloc(subBuffer, GCHandleType.Pinned);
var ptr = handle.ToIntPtr();
var val = (T)Marshal.PtrToStructure(ptr, typeof(T));
ptr.Free();
Peek += size;
Peek = ( Peek + ( Align - 1 ) ) & ~( Align - 1 );
return val;

但是,如果您的用例存在性能问题,那么提供硬编码的专用版本可能不是一个坏方法,因为没有任何明显的替代方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2020-05-23
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    相关资源
    最近更新 更多