C#重写机制与CAD图元开发要点

在C#中,重写(Override)是面向对象编程的核心概念,用于子类为继承自父类的虚方法(virtual)、抽象方法(abstract)或已重写的方法提供新的实现。在CAD(如AutoCAD)二次开发中,对图元进行重写通常意味着创建自定义实体,这需要深入理解CAD的API和对象模型。

C# 方法重写的基本用法

重写通过 override 关键字实现,其基本规则如下:

特性 基类方法 子类方法 说明
虚方法重写 使用 virtual 修饰 使用 override 修饰 最常见的重写形式,提供多态性。
抽象方法实现 使用 abstract 修饰 使用 override 修饰 子类必须提供实现。
密封重写 已使用 virtual 或 override 使用 override 和 sealed修饰 阻止该方法的进一步重写。
隐藏(非重写) 任何可访问方法 使用 new 修饰 创建新方法,不参与多态,不推荐轻易使用。

核心代码示例:

csharp 复制代码
public class BaseEntity
{
    // 1. 虚方法:提供默认实现,允许子类重写
    public virtual void Draw()
    {
        Console.WriteLine("绘制基础图元");
    }

    // 2. 抽象方法:无实现,强制子类重写 public abstract double CalculateArea();
}

public class MyCircle : BaseEntity
{
    // 使用 override 重写虚方法 public override void Draw()
    {
        base.Draw(); // 可选:调用基类实现 Console.WriteLine("绘制自定义圆形");
        // 添加自定义绘制逻辑 }

    // 必须重写抽象方法
    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

CAD二次开发中重写图元的注意事项

在AutoCAD等CAD平台进行二次开发时,创建自定义图元(即重写或扩展原生实体)是一项高级任务,需严格遵循其API规范。

1. 核心机制:从原生类派生

AutoCAD .NET API允许从特定原生类(如 Entity)派生以创建自定义对象。关键类是 CustomObject 及其子类,但更常见的做法是重写已有实体的行为或创建全新的 DBObject。

基本步骤示例:

csharp 复制代码
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;

// 自定义实体类必须继承自相应的CAD基类,例如Entity
public class MyCustomEntity : Entity
{
    // 必须重写的核心方法
    public override void SubWorldDraw(WorldDraw draw)
    {
        // 实现自定义的图形绘制逻辑
        // 例如,使用draw.Geometry.Circle等绘制图元
        base.SubWorldDraw(draw);
    }

    public override bool WorldDraw(WorldDraw wd)
    {
        // 处理世界空间中的绘制
        return base.WorldDraw(wd);
    }

    public override void GetGripPoints(
        GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, 
        GetGripPointsFlags bitFlags)
    {
        // 重写以定义自定义夹点
        base.GetGripPoints(grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
    }

    // 必须实现的事务处理克隆    public override DBObject Clone()
    {
        MyCustomEntity cloned = base.Clone() as MyCustomEntity;
        if (cloned != null)
        {
            // 深拷贝自定义字段 }
        return cloned;
    }
}

2. 必须注意的关键事项

注意事项 说明与解决方案
正确的类继承 必须从CAD API中允许派生的类继承,如 Entity、Curve 或 CustomObject。直接重写密封类(如 DBPoint)通常不被允许。
重写核心图形方法 WorldDraw、ViewportDraw 和 SubWorldDraw 是图形显示的核心,必须正确重写以确保图元在所有视图和布局中正确渲染。
处理对象持久化 自定义实体必须正确序列化和反序列化。需重写 DwgOut 和 DwgIn 方法,或使用 RXObject 类进行注册,并妥善管理自定义数据的读写。
注册自定义类 在CAD中使用自定义实体前,必须使用 RXClass 机制向数据库运行时注册该类,否则CAD无法识别和加载它。
夹点与编辑行为 重写 GetGripPoints 和 MoveGripPointsAt 以支持用户通过夹点交互式编辑你的图元。
边界框计算 重写 GetGeomExtents 方法,返回图元的精确边界框,这对于缩放、重生成和选择至关重要。
与命令流和事务集成 自定义实体的创建、修改和删除必须完全封装在CAD事务(Transaction)中,确保数据一致性和撤销/重做功能正常工作。
性能优化 在重写的绘制方法中,避免复杂计算。对于复杂几何图形,考虑使用代理图形或根据视图细节级别(LOD)简化图形。
资源管理 如果自定义实体使用了非托管资源(如句柄、内存),必须确保正确实现 Dispose 模式或在事务回滚时进行清理,防止内存泄漏。
兼容性与版本控制 为自定义实体的数据存储结构定义版本号,确保未来版本的程序能正确读取旧版本创建的图元。

3. 高级实践:使用自定义对象创建器

通常,更推荐使用 CustomObject 创建全新的对象类型,而非直接重写现有图元。这需要实现 ICustomObject 接口和相应的创建器。

csharp 复制代码
// 简化的自定义对象创建示例
public class MyEntityCreator : ICustomObjectCreator
{
    public void CreateCustomObject(ObjectId objectId)
    {
        using (Transaction tr = objectId.Database.TransactionManager.StartTransaction())
        {
            // 创建自定义实体实例
            MyCustomEntity ent = new MyCustomEntity();
            // ... 设置实体属性 ...

            BlockTableRecord btr = tr.GetObject(
                objectId, OpenMode.ForWrite) as BlockTableRecord;
            btr.AppendEntity(ent);
            tr.AddNewlyCreatedDBObject(ent, true);

            tr.Commit();
        }
    }
}

总结 :在C#中进行CAD图元重写,本质是遵循CAD平台的特定对象模型进行继承和扩展。关键在于准确重写图形绘制、数据持久化和用户交互相关的方法 ,并严格在CAD的事务管理和内存管理框架内操作。务必参考对应CAD版本(如AutoCAD)的官方 .NET API 文档,因为具体可重写的类和方法会因版本而异。


参考来源

相关推荐
淡海水3 小时前
10-01-互操作-C#与C++边界的内存管理
unity·c#·游戏引擎·.netcore·gc
WarPigs5 小时前
C#把byte[]以十六进制打印,带分割符
c#
暴走约伯6 小时前
【VFX工具链源码拆解 04】拯救丢失的绑定:Timeline 一键克隆与层级相对路径重映射算法
unity·c#·游戏引擎·硬件工程
1-1=06 小时前
C# 反射
c#·.net·.netcore
步步为营DotNet7 小时前
.NET 可观测性选型:Metrics、ActivitySource、EventSource 到底该用哪个
c#·.net·metrics·可观测性
吃一碗粉只付一碗钱19 小时前
16-SqlSugar多库ConfigId与按实体选连接
sqlserver·c#
rockey62720 小时前
AScript之字符串模板
c#·.net·script·expression·动态脚本
will_net21 小时前
Redis集群部署+Redis 链接地址放入Aollo +c#项目接入Redis
redis·c#·bootstrap
BuHuaX1 天前
Lua 与 ToLua:运行机制及热更新原理
开发语言·unity·junit·c#·lua