c#:运行时数据类型转换
本文关键字:类型转换 数据 运行时 | 更新日期: 2023-09-27 18:04:10
这是我自己第一次使用StackOverflow。我以前在这里已经找到了很多问题的答案,所以我想我也应该试着问自己一些问题。
我正在做一个小项目,我现在有点卡住了。我知道解决问题的方法——只是不是我想要的方法。
该项目包括一个我决定自己编写的NBT解析器,因为它将用于或多或少自定义的NBT文件变体,尽管核心原则是相同的:为特定类型的标签预定义"关键字"的二进制数据流。我决定尝试为所有不同类型的标签创建一个类,因为标签的结构非常相似——它们都包含类型和有效负载。这就是我被困住的地方。我希望负载具有一个特定的类型,当显式转换隐式完成时,会抛出错误。
我能想到的最好的方法是使有效载荷类型为Object或动态,但这将允许所有的转换隐式完成:
Int64 L = 90000;
Int16 S = 90;
dynamic Payload; // Whatever is assigned to this next will be accepted
Payload = L; // This fine
Payload = S; // Still fine, a short can be implicitly converted to a long
Payload = "test"; // I want it to throw an exception here because the value assigned to Payload cannot be implicitly cast to Int64 (explicit casting is ok)
有什么办法吗?我想通过某种方式告诉c#解决这个问题,从现在开始,即使Payload是动态的,如果赋值不能隐式地转换为当前值的类型,它将抛出异常——当然,除非显式地完成。
我可以接受其他方式来完成这个任务,但我想避免这样的事情:
public dynamic Payload
{
set
{
if(value is ... && Payload is ...) { // Using value.GetType() and Payload.GetType() doesn't make any difference for me, it's still ugly
... // this is ok
} else if(...) {
... // this is not ok, throw an exception
}
... ... ...
}
}
您考虑过使用泛型吗?这将自动为您提供编译时检查哪些转换是允许的。
class GenericTag<T>
{
public GenericTag(T payload)
{
this.Payload = payload;
}
public T Payload { set; get; }
}
// OK: no conversion required.
var tag2 = new GenericTag<Int64>(Int64.MaxValue);
// OK: implicit conversion takes place.
var tag1 = new GenericTag<Int64>(Int32.MaxValue);
// Compile error: cannot convert from long to int.
var tag4 = new GenericTag<Int32>(Int64.MaxValue);
// Compile error: cannot convert from string to long.
var tag3 = new GenericTag<Int64>("foo");
如果你知道你需要Int64,为什么不使用Convert.ToInt64呢?