V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
geelaw
V2EX  ›  分享发现

如何在 C# 里写出零额外开销(避免虚拟方法调用)的 CRTP 成语

  •  
  •   geelaw · 2020-10-03 21:23:28 +08:00 · 2152 次点击
    这是一个创建于 1521 天前的主题,其中的信息可能已经有所发展或是发生改变。

    考虑 C++ 代码

    #include<iostream>
    
    template <typename T>
    struct Base
    {
      T &Foo()
      {
        // MSVC 需要这个提示来优化 static_cast 的空指针检查。
        // __assume(this != nullptr);
        static_cast<T *>(this)->FooImpl();
        return *static_cast<T *>(this);
      }
    protected:
      ~Base() = default;
    };
    
    struct Derived : Base<Derived>
    {
    private:
      friend Base<Derived>;
      void FooImpl() { std::cout << "没有虚拟方法调用" << std::endl; }
    };
    

    问题是如何在 C# 里做出等价实现,满足:

    • 没有虚拟方法调用,或者子类可以决定 FooImpl 是否虚拟。
    • 至少在运行时保证 Base 的泛型参数是正确的子类。
    • 除非运行时使用反射作弊,否则不能破坏类的封装(需要实现有限程度的 friend),且编译期也不能破坏封装。

    第一个问题可以通过利用 CLR 对泛型参数实例化为 struct 时的优化实现,第二个则需要巧妙设置对应 struct 的接口和实现,使只有 Base 及其子类可以正常访问方法。

    详见 全文(英文)

    4 条回复    2021-06-25 16:12:48 +08:00
    lxilu
        1
    lxilu  
       2020-10-03 22:55:42 +08:00 via iPhone
    成语?
    geelaw
        2
    geelaw  
    OP
       2020-10-04 00:18:01 +08:00
    @lxilu #1 idiom
    lxilu
        3
    lxilu  
       2020-10-04 13:40:38 +08:00
    一般不会认为这是语吧,感觉成文 /成法 /惯用法更好,你这样好似句柄
    nullcoder
        4
    nullcoder  
       2021-06-25 16:12:48 +08:00
    666
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6069 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 02:21 · PVG 10:21 · LAX 18:21 · JFK 21:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.