【问题标题】:C#: How to determine some object type generically given instance of objectC#:如何确定一般给定对象实例的某些对象类型
【发布时间】:2010-07-16 17:00:52
【问题描述】:

我需要为上下文概述一些背景信息。请多多包涵,我会尽量简化我的问题:

我有一个对象继承自另一个对象。我们将调用第一个对象 Fruit 和第二个 Apple。因此,我将 Apple 声明如下:

public class Apple : Fruit
{
    public string appleType;
    public string orchardLocation;
    // etc.
}

而Fruit对象如下:

public class Fruit
{
    public int fruitID;
    public int price;
    // etc.
}

所以 Apple 继承自 Fruit。假设我有许多其他水果类型都继承自 Fruit:香蕉、橙子、芒果等。

在我的应用程序中,我保持了在 Session 中将特定类型的水果存储为该类型对象的能力,因此我可能在其中有一个 Apple 对象或一个 Banana 对象。我有一个方法可以从会话中检索当前的 Fruit,写法如下:

protected Fruit GetModel(int fruitID)
{
   // code to retrieve the fruit from the Session
   // fruitID could be the ID for an Apple or Banana, etc.
}

有时,我需要从 Session 中提取水果,更新一些关于它的内容,然后将其上传回 Session。我可以这样做:

Apple myApple = (Apple)GetModel(fruitID);
myApple.orchardLocation = "Baugers";
UpdateModel(myApple); // just overwrites the current fruit in the Session

现在我的问题。我现在需要从 Session 中提取对象,更新水果本身的特定内容(例如价格),然后将相同的对象上传回 Session。直到现在,我一直都知道对象的类型,所以现在就我而言——如果我知道水果的类型——我可以说:

Apple myApple = (Apple)GetModel(fruitID);
myApple.price = "4";
UpdateModel(myApple);

但这一次,我试图让它对 Fruit 本身更通用,并且并不总是知道子类型。如果我尝试从 Session 中提取 Fruit 对象本身(不进行强制转换),对其进行更新,然后将其上传回来,我现在只是丢失了我的子对象(Apple)并且在 Session 中只有一个 Fruit 对象。所以我需要一种方法,一般来说,在 Session 中创建对象类型的新实例,对其进行更新,然后将其重新上传。

我知道一个名为 GetType() 的 Object 的 .NET 方法,它返回您调用它的对象类型的 System.Type,假设该对象继承自 Object。但我无法做到这一点,而且我不想让 Fruit 从 Object 继承。

所以我将以我想要的伪代码版本结束:

public updateModelPrice(int price, fruitID)
{
    FigureOutType fruit = (FigureOutType)GetModel(fruitID);
    fruit.price = price;
    UpdateModel(fruit);
}

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 如果只是更新价格,那么您只需投射到 Fruit。如果它可能是 appleType,那么您仍然有问题。
  • 另外一点与您的问题并不密切相关:所有 .NET 类都继承自 Object,因此您已经免费获得了 GetType。 (虽然你不需要它来做你正在尝试的事情。)

标签: c# generics inheritance


【解决方案1】:

由于priceFruit 的成员,因此您无需弄清楚子类型。你可以这样做:

public updateModelPrice(int price, fruitID)
{
    Fruit fruit = GetModel(fruitID);
    fruit.price = price;
    UpdateModel(fruit);
}

【讨论】:

  • 问题是我想在 Session 中维护 Apple 对象及其所有 Apple 属性。如果我将对象转换为一个 Fruit,然后将其上传回 Session,我现在失去了我的 Apple 属性;我所拥有的只是会话中的一个 Fruit 对象
  • @Matt:看我的回答;即使您将苹果装箱为Fruit,您仍然可以通过使用is 进行测试以找出它是什么并将其转换回Apple。您的Apple 仍然是Apple - 它不会变成Fruit,只是用作一个。
  • @Matt - 转换对象实例不会改变底层实例的类型:它仍然是 Apple 并且在代码的其他部分,您仍然可以将实例视为 @987654331 @ 再次投射。
  • 问题中的 @Jeff GetModel 被声明为返回 Fruit,因此您的示例中不需要演员表。
  • @Phil - 哎呀,已修复。谢谢!
【解决方案2】:

一个简单的测试就可以了

如果(obj 是苹果)

其中 obj 是对象,Apple 是您正在测试的类型

顺便说一句,您创建的每个类都继承自对象

【讨论】:

    【解决方案3】:

    如果您不知道它是香蕉还是苹果at run-time 您可以使用 Fruit 对象做什么。

    Apple myApple = (Apple)GetModel(fruitID);
    

    你必须知道,它是一个苹果来做任何与Apple对象相关的事情,所以你必须将Fruit对象转换为Apple类型。

    也许你可以尝试更新你的UpdateModel方法来处理Fruit类型。

    【讨论】:

      【解决方案4】:

      您可以在运行时使用is 关键字来确定Fruit 的实际类型:

      if(fruit is Apple)
          DoAppleStuff();
      else if(fruit is Orange)
          Orange o = (Orange)fruit;
      
      // etc
      

      【讨论】:

        【解决方案5】:

        试试这个:

        public void updateFruitModel<T>(int price, int fruitId) where T : Fruit
        {
            T fruit = (T)GetModel(fruitId);
            fruit.price = price;
            UpdateModel(fruit);
        }
        

        【讨论】:

          猜你喜欢
          • 2020-11-08
          • 1970-01-01
          • 2013-03-04
          • 1970-01-01
          • 1970-01-01
          • 2018-02-24
          • 2016-09-06
          • 2011-01-14
          相关资源
          最近更新 更多