【问题标题】:Equivalent of c# class virtual member in TypeScriptTypeScript 中 c# 类虚拟成员的等价物
【发布时间】:2018-04-27 17:28:04
【问题描述】:

所以在 C# 中,当我创建模型类和延迟加载时,我会这样做:

public int? User_ID { get; set; }
public int? Dept_ID { get; set; }

然后在我的班级再往下一点,我会像这样弹出我的虚拟机:

public virtual User User {get; set;}
public virtual Department Dept {get; set;}

我将如何在 Typescript 中执行此操作?像这样?:

User_ID: number;
Dept_ID: number;
User: User;
Dept: Department;

我不认为接口是我想要/需要的......但是再次受保护似乎也不正确。有些东西告诉我,我在这里缺少一个明显的答案。

【问题讨论】:

    标签: javascript c# typescript oop overriding


    【解决方案1】:

    以下内容同样适用于 TypeScript 和 JavaScript:

    没有等价物。

    根据定义,JavaScript 中的每个成员访问都受制于动态调度。这是因为 JavaScript 中的成员访问在道德上是哈希表中的键查找。

    一个对象可以声明一个与它通过原型链继承的具有相同键的成员,从而隐藏继承的成员,但这与虚拟性不同,虚拟性是语言中不存在的概念.

    【讨论】:

    • 确实有道理。所以基本上就像我在这里做的那样加载额外的对象,这和它会得到的一样好。谢谢!
    • 我对最后一段有点困惑。在打字稿中,如果我有带有方法 M 的类 A,并且类 B 扩展了 A 并且还声明了方法 M,那么 let x: A = new B(); x.M() 将调用 B 的实现(即使变量是 A 类型)。这看起来像虚拟调度而不是影子。
    • 由于查找的工作原理,它会出现阴影。每当执行访问时,首先搜索对象,然后是对象的原型,然后是原型的原型,以此类推。委托是基本原则。请注意,您应用于变量的类型注释无论如何都不会对运行时行为产生任何影响。
    • 是的,我想我明白了。但是在 C# 中,阴影意味着在上面的示例中将调用 A 的实现。并且观察到的行为(无论实现细节如何)都将被视为压倒一切。
    • @Evk 在 C# 中,被调用的方法取决于引用的编译时类型和声明 (virtual/ override)。在 JavaScript 中,这些都不重要
    【解决方案2】:

    是的,有..

    //non-abstract or abstract class
    class A {
        
        // The virtual method
        protected virtualStuff1?():void;
    
        public Stuff2(){
            //Calling overridden child method by parent if implemented
            this.virtualStuff1 && this.virtualStuff1();
            alert("Baseclass Stuff2");
        }
    }
    
    //class B implementing virtual method
    class B extends A{
        
        // overriding virtual method
        public virtualStuff1()
        {
            alert("Class B virtualStuff1");
        }
    }
    
    //Class C not implementing virtual method
    class C extends A{
     
    }
    
    var b1 = new B();
    var c1= new C();
    b1.Stuff2();
    b1.virtualStuff1();
    c1.Stuff2();
    

    【讨论】:

    • 我想提一下,有override关键字,所以你会有public override virtualStuff1(){ }
    【解决方案3】:

    我使用箭头函数作为类的属性来实现这一点(注意这是在 ts 中,但如果你对现代 js 很方便,它应该可以工作):

    class baseClass {
        doSomething = () => {};
    }
    
    class derivedClass extends baseClass {
        constructor() {
            this.doSomeThing = () => { console.log('something'); };
        }
    }
    

    【讨论】:

      【解决方案4】:

      Javascript 和 Typescript 中的所有方法在技术上都是虚拟的,因为没有什么可以阻止您覆盖任何方法。

      【讨论】:

        猜你喜欢
        • 2015-09-06
        • 2013-08-25
        • 2010-09-07
        • 2011-07-22
        • 2018-02-24
        • 1970-01-01
        • 2021-03-22
        • 2011-01-30
        • 1970-01-01
        相关资源
        最近更新 更多