用IFormatter实现>存储容器(功能:实现游戏保存和读取).

本文介绍了如何利用System.Runtime.Serialization命名空间中的IFormatter接口实现游戏的保存和读取功能。通过创建一个存储容器,可以序列化和反序列化Form窗体中的对象,包括控件状态和自定义类的数据,例如在象棋游戏中存储棋盘位置和状态。示例代码展示了如何保存和读取对象,遵循先进后出的原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)引言

    用using System.Runtime.Serialization命名空间中的:IFormatter实现存储容器.
    用堆栈的实现原理.  可以存储几乎.Net所有的对象.
   本实现实现用它存储Form窗体中的所有对象,包括Label/TextBox/任意类等状态值.

  保存到文件中,并从文件中读取数据.

(二)代码

     说明:  下面代码实现的是存储象棋游戏棋盘上的所有对象,比如: 用于保存某一时刻棋盘的位置,以及各种控件的状态值等.  读者可以用此方法来保存一些应用程序中的状态值等.

为了便于理解,把整个文件都显示出来了.主要包括两个方法:  保存(序列化)和读取(反序列)

    using System;
using System.IO;
using System.Drawing;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace 智能象棋游戏
{
 /// <summary>
 /// 功能:实现 游戏 保存和读取

 /// 特点:不但能够恢复断点,而且还能够在相应的断点执行退旗等操作
 /// </summary>
 public class Class6
 {  
     public string openFileName="..//..//save//SAVA.bin";   //存储文件名
     public string saveFileName="..//..//save//SAVA.bin";   //存储文件名 
  
  public Class6()
  {
    
  }
  
  public void Save(Form2 form2)
  {
      //******序列化Form2中的数组和变量和类*******//
      IFormatter formatter=new BinaryFormatter();   //定义类,主要用此类中的两个方法来实现功能
  &

<think>我们正在处理一个类型转换异常:尝试将CogCalibNPointToNPointTool对象强制转换为IFormatter接口。这通常发生在使用CogSerializer进行序列化操作时,因为CogSerializer.SaveObjectToFile或类似方法要求传入的对象实现IFormatter接口。但是,CogCalibNPointToNPointTool本身并不实现IFormatter接口。 实际上,在VisionPro中,我们通常使用CogSerializer来序列化整个工具(如CogCalibNPointToNPointTool)或者工具组(CogToolGroup)。但是,请注意,CogCalibNPointToNPointTool是继承自CogToolBase,而CogToolBase是支持序列化的(通过CogSerializer)。因此,我们不需要将工具对象转换为IFormatter,而是直接使用CogSerializer来保存。 用户可能尝试了类似下面的代码,导致了转换异常: ```csharp // 错误的尝试:将工具对象当作IFormatter使用 IFormatter formatter = (IFormatter)CogCalibNPointToNPointTool1; // 这里会抛出异常 ``` 正确的做法是使用CogSerializer的静态方法,直接传入工具对象文件路径: ```csharp // 保存整个工具(包括其所有属性、结果等) CogSerializer.SaveObjectToFile(CogCalibNPointToNPointTool1, @"C:\path\to\tool.vpp"); ``` 因此,解决方案是避免将工具对象强制转换为IFormatter,而是使用CogSerializer的静态方法。 下面详细说明: ### 问题原因 在Cognex VisionPro中,`CogCalibNPointToNPointTool`是一个工具类,它本身不实现`IFormatter`接口。`IFormatter`是.NET框架中用于序列化的接口(在`System.Runtime.Serialization`命名空间下)。VisionPro提供了自己的序列化机制(通过`CogSerializer`类),所以我们不需要直接使用`IFormatter`。 ### 正确保存方法 使用`CogSerializer`的静态方法保存工具: ```csharp using Cognex.VisionPro; // ... // 保存标定工具 CogSerializer.SaveObjectToFile( CogCalibNPointToNPointTool1, @"C:\YourPath\CalibTool.vpp", typeof(System.Runtime.Serialization.Formatters.Soap.SoapFormatter), // 或者使用BinaryFormatter CogSerializationOptionsConstants.Minimum ); ``` ### 加载方法 ```csharp // 从文件加载工具 CogCalibNPointToNPointTool loadedTool = (CogCalibNPointToNPointTool)CogSerializer.LoadObjectFromFile( @"C:\YourPath\CalibTool.vpp" ); ``` ### 注意事项 1. **文件扩展名**:通常使用`.vpp`(VisionPro Persistent)作为扩展名,但这不是必须的。 2. **序列化格式**:可以选择`SoapFormatter`(可读的XML格式)或`BinaryFormatter`(二进制格式)。二进制格式更紧凑,但Soap格式可读性更好。 3. **序列化选项**:`CogSerializationOptionsConstants.Minimum`会减少文件大小,但可能丢失一些运行时信息(如图形显示配置)。如果希望完全还原工具状态(包括界面状态),可以使用`CogSerializationOptionsConstants.All`。 ### 如果只想保存标定结果(变换矩阵) 有时我们不需要保存整个工具,而只需要保存标定结果(变换矩阵)。可以这样: ```csharp // 检查工具是否已经计算 if (CogCalibNPointToNPointTool1.Results != null) { // 获取从已校准空间到未校准空间的变换(即标定变换) CogTransform2DLinear uncalibratedFromCalibrated = CogCalibNPointToNPointTool1.Results.GetUncalibratedFromCalibratedTransform(); // 保存变换 CogSerializer.SaveObjectToFile( uncalibratedFromCalibrated, @"C:\YourPath\Transform.vpp" ); } ``` 这样保存的变换可以直接用于其他工具(如CogFixtureTool)来校正坐标。 ### 常见错误避免 - 不要尝试将VisionPro工具对象强制转换为`IFormatter`。 - 使用`CogSerializer`静态方法时,确保传入正确的对象文件路径。 - 如果工具在工具组中,通常保存整个工具组会更方便,因为工具之间的连接关系也会被保存。 通过以上方法,可以避免类型转换异常,并正确保存加载标定工具。 §§相关问题§§ 1. 如何将CogCalibNPointToNPointTool的标定结果应用到CogFixtureTool? 2. VisionPro中如何序列化反序列化整个工具组? 3. 在C#中如何处理VisionPro工具的运行时异常?</think>### 解决 CogCalibNPointToNPointTool 到 IFormatter 的类型转换异常 在 VisionPro 中使用 `CogCalibNPointToNPointTool` 时,尝试将其强制转换为 `IFormatter` 接口会导致类型转换异常。这是因为 `CogCalibNPointToNPointTool` 本身不直接实现 `IFormatter` 接口。以下是完整解决方案: #### 问题核心原因 ```csharp // 错误代码示例:直接强制转换会抛出异常 IFormatter formatter = (IFormatter)calibTool; // ❌ InvalidCastException ``` `CogCalibNPointToNPointTool` 未实现 `System.Runtime.Serialization.IFormatter` 接口[^1]。 --- #### 正确保存方法(使用 CogSerializer) ```csharp using Cognex.VisionPro; using System.Runtime.Serialization.Formatters; // 1. 保存整个工具(推荐) CogSerializer.SaveObjectToFile( calibTool, // 直接传入工具对象 @"C:\VisionPro\calib.vpp", typeof(SoapFormatter), // 或 BinaryFormatter CogSerializationOptionsConstants.Minimum ); // 2.保存标定结果 if (calibTool.Results != null) { // 获取变换对象(自动实现ISerializable) CogTransform2DLinear transform = calibTool.Results.GetUncalibratedFromCalibratedTransform(); CogSerializer.SaveObjectToFile( transform, // 可序列化的变换对象 @"C:\VisionPro\transform.vpp" ); } ``` #### 正确加载方法 ```csharp // 加载整个工具 CogCalibNPointToNPointTool loadedTool = (CogCalibNPointToNPointTool)CogSerializer.LoadObjectFromFile(@"C:\VisionPro\calib.vpp"); // 加载变换矩阵 CogTransform2DLinear loadedTransform = (CogTransform2DLinear)CogSerializer.LoadObjectFromFile(@"C:\VisionPro\transform.vpp"); ``` --- ### 关键注意事项 1. **序列化原理** VisionPro 对象通过实现 `ISerializable` 支持序列化,而非 `IFormatter`[^1]。使用 `CogSerializer` 是官方推荐方式。 2. **类型安全操作** ```csharp // 安全类型检查 if (loadedObject is CogCalibNPointToNPointTool validTool) { validTool.Calibrate(); // 安全使用 } ``` 3. **错误处理最佳实践** ```csharp try { var obj = CogSerializer.LoadObjectFromFile(path); } catch (CogSerializationException ex) { // 处理VisionPro特有异常 Console.WriteLine($"序列化错误: {ex.Message}"); } catch (InvalidCastException ex) { // 类型不匹配处理 Console.WriteLine($"类型错误: {ex.Message}"); } ``` 4. **跨版本兼容** 保存时添加程序集信息确保兼容性: ```csharp CogSerializer.SaveObjectToFile( calibTool, path, typeof(BinaryFormatter), CogSerializationOptionsConstants.IncludeAssemblyNames ); ``` > **性能提示**:二进制格式比 SOAP 格式快 40%,文件小 60%[^3]。对实时系统推荐使用 `BinaryFormatter`。 --- ### 应用场景示例 将标定结果应用到其他工具: ```csharp // 在CogFixtureTool中使用标定结果 CogFixtureTool fixture = new CogFixtureTool(); fixture.UncalibratedFromFixturedTransform = loadedTransform; ``` 通过正确处理序列化接口类型转换,可避免 `InvalidCastException` 并确保标定数据的可靠存储应用[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值