选择要实例化的类C#

4
我想做的是基于传递的括号选择适当的类进行实例化。 目前我有两个类(ClassA和ClassB),根据括号使用2种不同的方法来调用它们。我希望只使用一个方法,根据传递的字符串括号来实例化ClassA或ClassB。
我不知道如何返回要使用的类对象。
我的旧方法是在Method A中调用要实例化的类,然后我可以使用它。 ClassA myclass = new ClassA();
我考虑过使用以下方法,但我不知道如何实例化对象o或在MyMethod返回时使用它。对象o似乎不能让我访问ClassA或ClassB中的公共字符串方法。
public class ClassA
{
    public ClassA()
    {
        //Do something for Class A
    }
    public string msgA()
    {
        return "Here is msg A";
    }
}

public class ClassB
{
    public ClassB()
    {
        //Do something for Class B
    }
    public string msgB()
    {
        return "Here is msg B";
    }
}

private string MyMethod()
{
    object o = GetClassToInstantiate("ClassA");
    //Use object o 
}

private object GetClassToInstantiate(string parameter)
{
    object temp = null;
    switch (parameter)
    {
        case "ClassA":
            temp = new ClassA();
            break;
    }

    return temp;
}

有什么建议可以解决这个可能非常简单的情况。

好的,你当前的代码确实是根据你传入的字符串参数返回一个对象。我不清楚你想要做什么,因为它已经在做了。 - Jon Skeet
从商业角度来看,您试图做什么? - mson
1
我认为OP可能处于学习曲线的那个阶段,接口和泛型还不在其工具库中。有了它们和一个工厂方法,这个问题就解决了。希望AdamRalph的答案能得到更多的赞同,因为它是正确的。 - Neil Hewitt
你是指括号还是参数? - Sam Meldrum
4个回答

15
你需要的是一个基类中的工厂方法:
enum ClassType { ClassA, ClassB }

class ClassBase
{
   public static ClassBase Create(ClassType  classType)
   {
       switch (classType)
       {
           case ClassType.ClassA: return new ClassA();
           case ClassType.ClassB: return new ClassB();
           default: throw new ArgumentOutOfRangeException();
       }
   }
}

class ClassA : ClassBase
{
}

class ClassB : ClassBase
{
}

请查看维基百科有关工厂方法模式的文章获取更多信息。


6
我建议您使用一个通用接口来定义您的类,同时创建一个独立的工厂类,其中包含以下通用的工厂方法:
class Program
{
    static void Main(string[] args)
    {
        IAnimal animal = AnimalFactory.CreateAnimal<Dog>();

        animal.Speak();

        Console.ReadKey();
    }
}

public abstract class AnimalFactory
{
    public static IAnimal CreateAnimal<T>() where T : IAnimal, new()
    {
        return new T();
    }
}

public interface IAnimal
{
    void Speak();
}

public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow");
    }
}

4
你想做的事情通常被认为不是很有用。完成后,你只知道它是一个对象,不知道它提供了哪些方法或属性。由于C#不支持(目前-即将在v4中)晚期绑定,所以你不能真正对结果做任何操作。
当A类和B类实现共同接口或继承自共同基类时,它变得更加有趣。在这种情况下,你可以拥有一个泛型方法,该方法实例化你的真实类但将其作为共同接口返回。这非常有用,例如在插件架构中。

4.0不提供后期绑定。后期绑定和动态类型之间存在微妙的区别。后期绑定在运行时绑定到类型。动态类型根本不绑定。这将允许您在运行时修改类型,而后期绑定则不能。 - Michael Meadows
好的,但它将允许您获取一个对象并尝试调用任意方法,就像那个OP所试图做的那样。 - Joel Coehoorn
是的,我并不是试图反驳你的观点,但我认为晚期绑定没有任何好处;你仍然会遇到类型不匹配的问题。晚期绑定只是将这些问题推迟到用户发现它们时,而不是在编译期间。动态类型允许您在运行时创建缺失的成员! - Michael Meadows

2
你最好使用设计模式来完成这个任务。在Gang of Four网站上查看抽象工厂和工厂方法模式。
抽象工厂:Abstract Factory 工厂方法:Factory Method

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接