代码之家  ›  专栏  ›  技术社区  ›  Bruno Brant

确定对象的类型

  •  3
  • Bruno Brant  · 技术社区  · 15 年前

    同样,我真的希望这不是一个意见问题;我想知道哪种方法是确定一个对象类型的最佳方法,该对象属于C#中的某个层次结构。我有两种方法来设计我的应用程序:

    1-在基类上使用属性:

    public abstract class Parent 
    {
        public abstract TypeOfObject TypeOfObject { get; }
    }
    
    public class Child1 : Parent
    {
        public override TypeOfObject TypeOfObject { get { return TypeOfObject.Child1 } }
    
        // ...
    }
    
    public class Child2 : Parent
    {
        public override TypeOfObject TypeOfObject { get { return TypeOfObject.Child2 } }
    
        // ...
    }
    
    public enum TypeOfObject 
    {
        Child1,
        Child2
    }
    
    public static void Main()
    {
        Parent p = new Child1();
    
        switch (p.TypeOfObject)
        {
            case TypeOfObject.Child1: _doSomethingWithChild1(p);break;
            case TypeOfObject.Child2: _doSomethingWithChild2(p);break;
        }
    }
    

    public abstract class Parent 
    {
        // ...
    }
    
    public class Child1 
    {
        // ...
    }
    
    
    public class Child2 : Parent
    {    
        // ...
    }
    
    public enum TypeOfObject 
    {
        Child1,
        Child2
    }
    
    public static void Main()
    {
        Parent p = new Child1();
    
        if (p is Child1) _doSomethingWithChild1(p);
        if (p is Child2) _doSomethingWithChild2(p);
    }
    

    每种选择的含义是什么?我认为2依赖于元数据,因此它的性能受到了更大的影响,但是1看起来不那么优雅。此外,我学会了做这1种方式在C++…我不确定是否有必要用C#这样做。

    编辑1:

    我添加了 覆盖 上面代码的关键字。

    编辑2:

    对不起,我可能还没说清楚。我将更好地说明这一点:

    例如 ,我有一个WPF Panel Children 属性,它返回我 UIElement s、 我需要知道某个元素的作用类型。。。在我的特殊情况下,用户在屏幕上绘制一个图形,因此我需要知道绘制了多少节点和多少连接,以便将其存储在数据库中。不幸的是,我不能使用多态性,对吧?我如何知道应该向nodes表还是connections表添加一行?

    3 回复  |  直到 15 年前
        1
  •  0
  •   Community Mohan Dere    8 年前

    您的使用示例是错误的(正如其他人所说的-使用多态性),但是可以合理地询问对象是什么类型的。

    我问了c一个类似的问题++ Testing a c++ class for features

    关于1和2之间的区别。两者都需要元数据。在案例1中,您正在创建它;在案例2中,您无论如何都在使用CLR创建的元数据。CLR可能比你做得更好,而且它还是要支付这些开销的

    像往常一样-如果你想知道哪一个更快的答案很简单-测量它然后看。我怀疑有明显的差别

        2
  •  10
  •   user395760 user395760    15 年前

    你做错了。听说过多态性(更精确地说是后期/动态绑定)吗?父级应该有一个抽象方法,如 doSomething() 由孩子们来执行 _doSomethingWithChild1 应该在里面 Child1.doSomething 等等,这就是OO 全部的 -好吧,不是全部,而是很大一部分!C++ FAQ是正确的,声称C++不面向对象。 virtual . 不仅添加另一个子类(您只需定义一个新的子类和方法,不需要修改开关或ifs)更容易/更少出错,而且很可能是最快的方法(每个JIT都值得使用 polymorphic inline caching ),它也很习惯,不太可能让你看到“WTF”的眼神;)

        3
  •  4
  •   Muad'Dib    15 年前

    第一种选择是不必要的。如果您查看对象(C#中所有对象的基),您将发现 GetType() 成员。

    在我们的产品代码中,我们经常使用方法2,主要用于“向下转换”,也就是说,将我的a基类转换为从所述基类派生的类。。。

    if ( myObject is Type1 ) dosomething();
    if ( myObject is Type2 ) dosomethingelse();
    

    as 接线员。。。。

    Type1 object1 = someotherobject as type1;
    if ( object1 != null ) dosomething();
    

    ((TypeFoo)object1).bar(); // if object 1 is NOT of TypeFoo you get an exception