C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

Viewのロック・アンロック2

こちらの続きです。
Viewのロック・アンロック1 - C#ATIA

C#にしてみました。

//cs
namespace Drw_View_Lock_UnLock {
    using System.Linq;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;//COMオブジェクトを操作するために必要
    using DRAFTINGITF;//Catiaのライブラリ
    using System.Collections.Generic;

    static class Program {
        static void Main() {
            var catia = (INFITF.Application)Marshal
                        .GetActiveObject("CATIA.Application");
            var ViewLock = new View_Lock_UnLock(catia);
            ViewLock.Execute();
        }
    }

    class View_Lock_UnLock {
        public View_Lock_UnLock(INFITF.Application Catia) {
            CatExtension.State = new CatiaContainer(Catia);
        }

        public void Execute() {
            if (CatExtension.State.Views.Count < 3) { return; }
            var lockStatus = CatExtension.State.Views.View3LockStatus();
            foreach (var view in CatExtension.State.ViewsEnumerable//①
                                    .Where((v, index) => index > 1)) {//③
                view.LockStatus = !lockStatus;
            }
            MessageBox.Show(string.Format("全てのビューを{0}しました",
                                lockStatus ? "アンロック" : "ロック"));
        }
    }

    class CatiaContainer {
        private INFITF.Application catia;

        public CatiaContainer(INFITF.Application cat) {
            Catia = cat;
            Setting();
        }

        ~CatiaContainer() {
            if (catia != null) { Marshal.ReleaseComObject(catia); }
        }

        public void Setting() {
            DrawDoc = catia.ActiveDocument as DrawingDocument;
            Views = DrawDoc.Sheets.ActiveSheet.Views;
        }

        public INFITF.Application Catia {
            get {
                return catia;
            }
            private set {
                catia = value;
            }
        }
        public DrawingDocument DrawDoc { get; private set; }
        public DrawingViews Views { get; private set; }
        public IEnumerable<DrawingView> ViewsEnumerable {//②
            get {
                return Enumerable.Range(1, Views.Count)
                                 .Select(i => Views.Item(i));
            }
        }
        public DrawingView View { get; set; }
    }

    static class CatExtension {
        public static CatiaContainer State { get; set; }

        public static bool View3LockStatus(this DrawingViews views) {
            return views.Item(3).LockStatus;
        }

        public static void SetLockStatus(this DrawingView view,
                                              bool lockStatus) {
                view.LockStatus = lockStatus;
        }
    }
}

あまりに大げさな気がします。 素直にVBAC#らしくないソース
にした方がすっきりしそうな気が・・・。

①の部分は②の部分でIEnumerable<DrawingView>にしているのですが、
本当はToEnumerable<T>のようなジェネリックにしたかったのですが、
COMオブジェクトが単なるオブジェクトなのか?コレクションなのか?
をどのように識別させれば良いのか判らず、出来ずに断念しました。

③部分はインデックス3以上のもののみを取得させたいのですが、
IEnumerable<DrawingView>にした際、本来のインデックスと
1つズレてしまいました。

Views.Item IEnumerable<DrawingView>
1 0
2 1
3 2

混乱の元になるので、非常に良くないですね。

それとCOMオブジェクトの解放は止めました。
新たにインスタンスを作成しているのならともかく、
CATIAの持っているオブジェクトを解放しても
CATIA自身が参照しているので、解放できていないのでは
ないのかな?と。 そもそもめんどくさいです。(本音)

本当の所がわからないので、ご存知の方いらっしゃいましたら
教えていただきたいです。