C#:如何在给定对象实例的情况下确定某种对象类型

C#:如何在给定对象实例的情况下确定某种对象类型,c#,generics,inheritance,C#,Generics,Inheritance,我需要概述一些背景信息以供参考。请耐心听我说,我会尽量简化我的问题: 我有一个从另一个对象继承的对象。我们将第一个对象称为水果,第二个对象称为苹果。因此,我宣布苹果公司如下: public class Apple : Fruit { public string appleType; public string orchardLocation; // etc. } public class Fruit { public int fruitID; publi

我需要概述一些背景信息以供参考。请耐心听我说,我会尽量简化我的问题:

我有一个从另一个对象继承的对象。我们将第一个对象称为水果,第二个对象称为苹果。因此,我宣布苹果公司如下:

public class Apple : Fruit
{
    public string appleType;
    public string orchardLocation;
    // etc.
}
public class Fruit
{
    public int fruitID;
    public int price;
    // etc.
}
protected Fruit GetModel(int fruitID)
{
   // code to retrieve the fruit from the Session
   // fruitID could be the ID for an Apple or Banana, etc.
}
水果对象如下所示:

public class Apple : Fruit
{
    public string appleType;
    public string orchardLocation;
    // etc.
}
public class Fruit
{
    public int fruitID;
    public int price;
    // etc.
}
protected Fruit GetModel(int fruitID)
{
   // code to retrieve the fruit from the Session
   // fruitID could be the ID for an Apple or Banana, etc.
}
所以苹果继承了水果。比如说,我还有很多其他水果类型都是从水果中继承来的:香蕉、橘子、芒果等等

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

public class Apple : Fruit
{
    public string appleType;
    public string orchardLocation;
    // etc.
}
public class Fruit
{
    public int fruitID;
    public int price;
    // etc.
}
protected Fruit GetModel(int fruitID)
{
   // code to retrieve the fruit from the Session
   // fruitID could be the ID for an Apple or Banana, etc.
}
有时候,我需要从会话中提取成果,更新一些关于它的信息,然后将其上传回会话。我可以这样做:

Apple myApple = (Apple)GetModel(fruitID);
myApple.orchardLocation = "Baugers";
UpdateModel(myApple); // just overwrites the current fruit in the Session
现在我的问题。我需要从会话中提取对象,更新特定于水果本身的内容(比如,价格),然后将相同的对象上传回会话。到目前为止,我一直都知道物体的类型,所以在我的例子中,如果我知道水果的类型,我可以说:

Apple myApple = (Apple)GetModel(fruitID);
myApple.price = "4";
UpdateModel(myApple);
但这一次,我试图让它更通用于水果本身,并不总是知道子类型。如果我试图从会话中提取水果对象本身(不强制转换),更新它,并将其上载回,那么我现在已经丢失了我的子对象(Apple),会话中只有一个水果对象。所以我需要一种方法,一般来说,在会话中创建一个对象类型的新实例,更新它,然后将其上传回

我知道一个名为GetType()的对象的.NET方法,它返回一个System.Type,即您调用它的对象类型,假设该对象继承自该对象。但我没能做到这一点,我不希望从对象继承水果

因此,我将以我想要的伪代码版本结束:

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

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

如果您在运行时不知道它是香蕉还是苹果
您可以对水果对象做什么

Apple myApple = (Apple)GetModel(fruitID);
你必须知道,苹果可以做任何与苹果对象相关的事情,所以你必须将水果对象转换为苹果类型


可能是您可以尝试更新您的
UpdateModel
方法来处理
Fruit
类型。

如果您在运行时不知道它是香蕉还是苹果
您可以如何处理Fruit对象

Apple myApple = (Apple)GetModel(fruitID);
你必须知道,苹果可以做任何与苹果对象相关的事情,所以你必须将水果对象转换为苹果类型


可能您可以尝试更新您的
UpdateModel
方法来处理
Fruit
类型。

由于
price
Fruit
的成员,因此您不需要计算子类型。您可以这样做:

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

由于
price
Fruit
的成员,因此不需要计算子类型。您可以这样做:

public updateModelPrice(int price, fruitID)
{
    Fruit fruit = GetModel(fruitID);
    fruit.price = price;
    UpdateModel(fruit);
}
您可以使用关键字在运行时确定
水果的实际类型:

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

// etc
您可以使用关键字在运行时确定
水果的实际类型:

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

// etc

一个简单的测试就可以了

if(obj是Apple)

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


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

一个简单的测试应该可以做到这一点

if(obj是Apple)

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

顺便说一下,您创建的每个类都继承自object

public void updateFruitModel<T>(int price, int fruitId) where T : Fruit
{
    T fruit = (T)GetModel(fruitId);
    fruit.price = price;
    UpdateModel(fruit);
}
public void updateFruitModel(int-price,int-fruitId),其中T:Fruit
{
T水果=(T)GetModel(水果ID);
水果价格=价格;
更新模型(水果);
}
试试这个:

public void updateFruitModel<T>(int price, int fruitId) where T : Fruit
{
    T fruit = (T)GetModel(fruitId);
    fruit.price = price;
    UpdateModel(fruit);
}
public void updateFruitModel(int-price,int-fruitId),其中T:Fruit
{
T水果=(T)GetModel(水果ID);
水果价格=价格;
更新模型(水果);
}

如果更新的只是价格,那么您只需将其转换为结果即可。如果它可能是appleType,那么您仍然有问题。另一个与您的问题不太相关的注意事项是:所有.NET类都继承自
对象
,因此您已经有了免费的
GetType
。(虽然你不需要它来做你看起来想要做的事情。)如果它是唯一一个更新的价格,那么你只需要将其付诸实施。如果它可能是appleType,那么您仍然有问题。另一个与您的问题不太相关的注意事项是:所有.NET类都继承自
对象
,因此您已经有了免费的
GetType
。(虽然你不需要它来做你看起来想要做的事情。)问题是我想在会话中维护Apple对象及其所有Apple属性。如果我将对象仅投射到一个水果上,然后将其上传回会话,我现在就失去了我的苹果属性;我只有一个水果的物体session@Matt:看我的答案;即使您将苹果包装成
水果
,您仍然可以通过使用
is
进行测试,找出它是什么,然后将其扔回
苹果
。你的
Apple
仍然是一个
Apple
-它不会变成
水果
,只是用作一个。@Matt-投射对象实例不会改变基础实例的类型:它仍然是一个
Apple
,在代码的其他部分,通过再次强制转换,您仍然可以将该实例视为一个
Apple
。@Jeff
GetModel
在问题中被声明为返回
Fruit
,因此您的示例中不需要强制转换。@Phil-哎哟,修复了。非常感谢。问题是我想在会话中维护Apple对象及其所有Apple属性。如果我将对象强制转换为一个水果,然后将其上传回会话,那么我现在已经丢失了