以高性能方式审核和验证对 C# 类和结构属性的更改
我有几个 C# 结构体,可以在一个非常大的数据文件中形成结构体。这些结构解释文件数据字中的位,并将它们转换为一流属性。这是一个例子:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TimeF1_MsgDayFmt
{
// Time Data Words
public UInt16 TDW1;
public UInt16 TDW2;
public UInt16 TDW3;
/// <summary>
/// Tens of milliseconds
/// </summary>
public UInt16 Tmn
{
// Bits.Get is just a helper method in a static class
get { return Bits.Get(TDW1, 0, 4); }
set
{
if (value > 9)
throw new ArgumentOutOfRangeException();
TDW1 = Bits.Set(TDW1, value, 0, 4);
}
}
/// Several other properties follow.
我需要做两件事,我认为这两件事是相关的。第一个是能够使用验证规则集合来验证整个类。我知道有几种方法可以做到这一点;最吸引我的是用这样的东西注释每个属性:
[ValidateRange(0,9)]
public UInt16 Tmn
{
get { return Bits.Get(TDW1, 0, 4); }
set
{
/// etc. Will probably no longer throw the ArgumentOutOfRangeException here.
...然后使用 Validator 类读取所有属性属性,根据注释规则检查每个属性值( s),并返回错误对象的集合。但我关心反思需要多长时间;这些结构必须具有极高的性能。
public List<Error> Validate(TimeF1_MsgDayFmt original)
我要做的第二件事是对财产变更进行审计;也就是说,对于每个已从其原始值更改的属性,我需要能够获取一个字符串,表示“Property foo 从 bar 更改为 baz。”为此,我希望一种比较“之前”和“之后”struct
的所有属性并记下差异的方法。
public List<string> Compare(TimeF1_MsgDayFmt original, TimeF1_MsgDayFmt new)
在这两种情况下,代码都将涉及迭代所有属性并以尽可能快的方式单独检查每个属性。
我该如何处理这个问题?
I have several c# structs that give shape to structures in a very large data file. These structs interpret bits in the file's data words, and convert them to first-class properties. Here is an example of one:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TimeF1_MsgDayFmt
{
// Time Data Words
public UInt16 TDW1;
public UInt16 TDW2;
public UInt16 TDW3;
/// <summary>
/// Tens of milliseconds
/// </summary>
public UInt16 Tmn
{
// Bits.Get is just a helper method in a static class
get { return Bits.Get(TDW1, 0, 4); }
set
{
if (value > 9)
throw new ArgumentOutOfRangeException();
TDW1 = Bits.Set(TDW1, value, 0, 4);
}
}
/// Several other properties follow.
I need to do two things, which I think are related. The first is to have the ability to validate the entire class, using a collection of validation rules. I know there are several ways to do this; the one that most appeals to me is to annotate each property with something like this:
[ValidateRange(0,9)]
public UInt16 Tmn
{
get { return Bits.Get(TDW1, 0, 4); }
set
{
/// etc. Will probably no longer throw the ArgumentOutOfRangeException here.
... and then use a Validator
class to read all of the property attributes, check each property value against the annotated rule(s), and return a collection of error objects. But I am concerned with how long the Reflection is going to take; these structures have to be extremely high-performing.
public List<Error> Validate(TimeF1_MsgDayFmt original)
The second thing I need to do is to perform auditing on property changes; that is, for each property that has changed from its original value, I need to be able to get a string that says "Property foo changed from bar to baz." To do that, I'd like a way to compare all properties of a "before" and "after" struct
, and note the differences.
public List<string> Compare(TimeF1_MsgDayFmt original, TimeF1_MsgDayFmt new)
In both cases, the code will involve iterating over all of the properties and examining each one individually, in a way that is as fast as possible.
How would I approach this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果问题是,读入结构的数据是否匹配附加约束,您首先必须弄清楚如何写下此类约束。 (在您的示例中,您编写了 [ValidateRange(0,9)] 作为此类约束之一)。
一旦您有办法写下约束,那么您就必须将数据读入相应的结构中,然后检查约束。 (在您的示例中,您提出了使用反射的想法)。
在我看来,写下此类约束的最简单且执行速度快的方法就是将它们简单地编写为附加的 C# 代码。对于您可以想象的每个约束,您可以添加一个类方法来检查约束并返回一个布尔值。您可以添加标准约束“CheckIt”来计算所有单独约束方法的合取。
编写约束应该很容易。我希望 C# 编译器内联其他方法,特别是如果它们很小并且不带参数(隐含类除外)。这应该会让他们很快。
如果 C# 编译器无法执行此操作,请切换到 C++,在其中您几乎可以强制内联。
If the issue is, Does the data read into a struct match additional constraints, you will first of all have to figure out how to write down such constraints. (In your example, you wrote [ValidateRange(0,9)] as one such constraint).
Once you have a means to write down the constraints, then you have to presumably read data into corresponding struct and then check the constraints. (In your example, you suggested the idea of using reflection).
It seems to me the easiest way to write down such constraints, that executes fast, is to simply write them as additional C# code. For each constraint you can imagine, you can add a method of the class that checks the constraint and returns a boolean. You can add a standard constraint "CheckIt" that computes a conjunction of all the individual constraint methods.
It should be easy to write the constraints. I'd expect the C# compiler to inline the other methods, especially if they are small and take no arguments (other than the implied class). That should make them fast.
If the C# compiler won't do it, switch to C++, where you can pretty much force inlining.