c# - 有什么方法可以防止/检测自动/隐式类型转换?
问题描述
考虑这些方法,每个方法都从输入缓冲区中提取字节:
byte ReadByte(List<byte> data); //removes and returns 1 byte
UInt16 ReadUInt16(List<byte> data); //removes and returns 2 bytes as a short
UInt32 ReadUInt32(List<byte> data); //removes and returns 4 bytes as an int
现在我有一个结构/类,如:
class Thing
{
public byte a{get;set;}
public UInt16 b{get;set;}
public UInt32 c{get;set;}
public byte d{get;set;}
public void Read(List<byte> data)
{
a = ReadByte(data);
b = ReadUInt16(data);
c = ReadUInt16(data); //BUG this is a 32bit data
d = ReadByte(data);
}
}
因为 ashort
会自动提升为 a int
,所以这段代码编译并运行良好,但引入了一种很难找到的错误——它读取的字节数比它应该读取的少 2 个字节,c
并且所有后续读取的值都是错误的。
是否有任何技术可用于确保当c
是 type时UInt32
,它不会接受 aUInt16
或其他合法类型?
理想情况下Thing
不会改变,但如果您的解决方案需要它,那没关系。
解决方案
答案是:对于您提供的方法不适用。
比如C#和.NET的CTS设计,就无法避免这样的编码错误。
但是就是说,您可以做的一件事是使用这样的通用方法:
static T Read<T>(this T instance, List<byte> data)
{
switch ( instance )
{
case byte value:
Console.WriteLine("Read byte");
return default;
case UInt16 value:
Console.WriteLine("Read UInt16");
return default;
case UInt32 value:
Console.WriteLine("Read Uint32");
return default;
default:
string message = $"Type not supported for Read<T> (only byte or UInt16/32): "
+ $"{typeof(T).Name}";
throw new ArgumentException(message);
}
}
class Thing
{
public byte a { get; set; }
public UInt16 b { get; set; }
public UInt32 c { get; set; }
public byte d { get; set; }
public void Read(List<byte> data)
{
a = a.Read(data);
b = b.Read(data);
c = c.Read(data);
d = d.Read(data);
}
}
这并没有提供绝对的方法来避免编码错误,而是少做,因为我们可以很容易地看到与我们操作的变量的匹配,就像使用字符串方法修改相同的字符串时一样。
测试
var list = new List<byte> { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
var instance = new Thing();
instance.Read(list);
输出
Read byte
Read UInt16
Read Uint32
Read byte
推荐阅读
- c - 在 C 中获得双重释放或损坏!prev
- javascript - API 不会返回数据(Google 表格/应用脚本)
- javascript - Javascipt:类中的静态字段创建错误
- mysql - 具有单个参数和多种数据类型的 MySQL 查询
- cmusphinx - CMUSphinx 最简单的关键字“唤醒词”示例?
- logging - 为什么张量板不显示所有指标?
- python - 尝试解压缩 tar.gz 文件并将其保存为文件夹中的多个可读文本文件,然后重新压缩它
- java - 使用递归的数字模式
- c++ - 为什么 operator() 在我的程序中被调用了两次?
- sonarqube - SonarQube WebApi /api/ce/task 调用中“状态”的可能值是什么?