简体   繁体   English

确定对象的类型

[英]Determining a Type of an Object

Again, I really hope this isn't a matter of opinion; 我再次希望这不是一个意见问题; I'm trying to know which is the best way to determine the type of an object that belongs to a certain hierarchy in C#. 我试图知道哪种是确定属于C#中某个层次结构的对象类型的最佳方法。 I have two ways to design my application: 我有两种方法来设计我的应用程序:

1 - Use a property on the base class: 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;
    }
}

2 - Use the is operator 2 - 使用is运算符

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);
}

What are the implications of each alternative? 每种选择的含义是什么? I think 2 has a greater performance hit since it relies on metadata, but 1 seems way less elegant. 我认为2由于依赖于元数据而具有更大的性能,但是1似乎不那么优雅。 Besides, I learned to do this the 1 way in C++... I'm not sure it's necessary to do so with C#. 此外,我学会了用C ++编写的这种方法......我不确定是否有必要用C#这样做。

EDIT 1: 编辑1:

I've added the override keyword to the code above. 我已将override关键字添加到上面的代码中。

EDIT 2: 编辑2:

I'm sorry, I've probably not made myself clear. 对不起,我可能没说清楚。 I will illustrate it better: 我会更好地说明一下:

For example , I have a WPF Panel object that has a Children property, which returns me UIElement s. 例如 ,我有一个WPF Panel对象,它有一个Children属性,它返回UIElement I need to know what type a certain element is to act upon it... in my particular case, the user is drawing a graph on the screen, so I need to know how many nodes and how many connections are drawn in order to store then at the database. 我需要知道某个元素在什么类型上行动...在我的特定情况下,用户在屏幕上绘制图形,所以我需要知道有多少节点和多少个连接被绘制以便存储然后在数据库。 I can't, unfortunately, use polymorphism for that, right? 不幸的是,我不能使用多态性,对吗? How will I know if I should add a line to my nodes table or to my connections table? 我怎么知道是否应该在我的节点表或连接表中添加一行?

You are doing it wrong™. 你做错了™。 Ever heard of polymorphism (late/dynamic binding to be more precise)? 曾经听说过多态(迟到/动态绑定更准确)? The parent should should have an abstract method like doSomething() to be implemented by the children, whatever was in _doSomethingWithChild1 should be in Child1.doSomething , etc. This is what OO is all - well, not all, but to a large part - about! 父应该有一个抽象的方法,比如doSomething()由孩子们实现, _doSomethingWithChild1应该在Child1.doSomething中等等。这就是OO的 全部 - 好吧,不是全部,但在很大程度上 -关于! The C++ FAQ is right claiming that C++ wouldn't be object oriented without virtual . C ++ FAQ正确地声称C ++在没有virtual的情况下不会面向对象。 Not only it's easier/less error-prone to add another child (you just define a new subclass and the method, no need to fiddle with switches or ifs) and very likely the fastest way possible (every JIT worth its salt uses polymorphic inline caching ), it's also idiomatic and less likely to get you that "WTF" stare ;) 不仅更容易/更不容易出错添加另一个孩子(你只需要定义一个新的子类和方法,不需要使用开关或ifs)并且很可能以最快的方式(每个JIT值得它的盐使用多态内联缓存) ),它也是惯用的,不太可能让你“WTF”盯着;)

the first alternative is not neccessary. 第一种选择不是必要的。 if you look at Object (the base for ALL objects in C#) you will find a GetType() member. 如果你看一下Object(C#中所有对象的基础),你会发现一个GetType()成员。

In our production code, we frequently use method 2, mainly for "down-casting" that is, casting my a base class to a class that is derived from said base class... 在我们的生产代码中,我们经常使用方法2,主要用于“向下转换”,即将我的基类转换为从所述基类派生的类...

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

we also use the as operator.... 我们也使用as运算符....

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

the nice thing about this, is that you won't get exceptions like you would if you tried something like this: 关于这个的好处是,你不会像你尝试过这样的事情那样得到例外:

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

Your use examples are wrong (as other have said - use polymorphism) but it can be reasonable to ask what type an object is. 您的使用示例是错误的(正如其他人所说的那样 - 使用多态)但是询问对象的类型是合理的。

I asked a similar question for c++ Testing a c++ class for features 我问了一个类似的问题,用于c ++ 测试c ++类的功能

Regarding the difference between #1 and #2. 关于#1和#2之间的区别。 Both require metadata. 两者都需要元数据 In case 1 you are making it, in case 2 you are using metadata made by the CLR anyway. 如果您正在使用案例1,则在案例2中您仍在使用CLR生成的元数据。 The CLR is probably better at it than you , and its paying that overhead anyway CLR可能比你更好,而且无论如何它支付了开销

As always - if you want to know which is faster the answers is simple - measure it and see. 一如既往 - 如果你想知道哪个更快,答案很简单 - 测量并查看。 I doubt there is a measurable difference 我怀疑是否存在可衡量的差异

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM