假设我有一个抽象类ObjectA。 ObjectC和ObjectB继承自ObjectA。从ObjectA继承的还有很多。
然后,我有一些根据对象类型执行某些操作的方法。
public void DoSomething(ObjectC data){}
public void DoSomething(ObjectB data){}
我想知道是否有一种方法可以根据对象的类型来调用所需的方法,这是因为我不知道我将得到哪种对象。
public void DoSomething(ObjectA data){
DoSomething(data);
}
当前我正在使用
public void DoSomething(ObjectA data){
if (data is ObjectB dataB){
DoSomething(dataB);
}else if (data is ObjectC dataC){
DoSomething(dataC);
}
}
我想知道是否有办法避免使用if/else
。
谢谢。
答案 0 :(得分:4)
执行此操作的传统方法是反转您的要求,并使用virtual
函数以@RuiJarimba在评论中描述的方式实现polymorphism
。例如,考虑以下三个类(我将您的ObjectX类重命名为ClassX):
public abstract class ClassA
{
public abstract void DoSomething();
}
public class ClassB : ClassA
{
public override void DoSomething()
{
//Do something that is ClassB specific
}
}
public class ClassC : ClassA
{
public override void DoSomething()
{
//Do something that is ClassC specific
}
}
ClassB
和ClassC
的每个实例本质上都是ClassA
(通过继承)。 ClassB
和ClassC
都实现了DoSomething
方法,该方法将覆盖ClassA
定义的抽象定义。现在,我可以获取任何ClassA
对象(由于ClassA
是抽象的,因此必须是ClassA
的子类的实例)并对其调用DoSomething()
并获得DoSomething()
的特定于类的实现。在下面的代码中,我创建了单独的实例。在现实生活中,通常会有ClassA
对象引用的集合,您会逐步调用相应的方法:
ClassA objectB = new ClassB();
ClassA objectC = new ClassC();
objectB.DoSomething(); //calls ClassB's version
objectC.DoSomething(); //calls ClassC's version
这不是您要问的,但我想这就是您想要的。
如果要保留相同的函数签名,可以将以下内容添加到ClassA
定义中:
public static void DoSomething<T>(T data) where T : ClassA
{
data.DoSomething(); //dispath through the right class using a virtual function
}
如果您这样做,那么它将起作用(使用上面创建的objectB
和objectC
实例:
ClassA.DoSomething(objectB); //calls ClassB's version
ClassA.DoSomething(objectC); //calls ClassC's version
新代码的作用是获取传递的对象(它必须是ClassA
子类的实例),然后简单地调用先前定义的虚函数,将事物分派到适当的类的实现。
答案 1 :(得分:1)
您可以使用is
运算符和强制转换。
检出:
https://dotnetfiddle.net/uvjHHV
using System;
public class Program
{
public abstract class ObjectA { }
public class ObjectB : ObjectA {}
public class ObjectC : ObjectA {}
public static void Main()
{
// You may get this instance from anywhere
Object o = new ObjectB();
if (o is ObjectB)
DoSomething((ObjectB) o);
else if (o is ObjectC)
DoSomething((ObjectC) o);
}
public static void DoSomething(ObjectB o) {
Console.WriteLine("Object B called");
}
public static void DoSomething(ObjectC o) {
Console.WriteLine("Object C called");
}
}
答案 2 :(得分:-1)
尝试使用接口。您可以使用相同的方法来处理多种类型。
using System;
namespace Demo
{
class Program
{
interface IAwesomeInterface
{
void DoSomething(int number);
void DoSomething(string strang);
void DoSomething(Person person);
}
class MyClass : IAwesomeInterface
{
public void DoSomething(int number)
{
number = number + 100;
Console.WriteLine(number);
}
public void DoSomething(string strang)
{
strang += " World";
Console.WriteLine(strang);
}
public void DoSomething(Person person)
{
person.Id = person.Id++;
person.Name += "Bar";
Console.WriteLine($"{person.Id} - {person.Name}");
}
}
static void Main(string[] args)
{
int someNumber = 3;
string strang = "Hello";
Person person = new Person();
person.Id = 1;
person.Name = "Foo";
MyClass myClass = new MyClass();
// Do something with a number
myClass.DoSomething(someNumber);
// Do something with a strang (string)
myClass.DoSomething(strang);
// Do something with a Person object
myClass.DoSomething(person);
Console.ReadKey();
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}