1

为了解释我的问题,这里是一个例子

namespace CheckAbstarct
{

class Program
{
    static void Main(string[] args)
    {
        myAbstarctClass mac1 = ObjectFactory.ObjectCreator("aaa");
        myAbstarctClass mac2 = ObjectFactory.ObjectCreator("bbb");
        mac1.changeMyString();
        mac2.changeMyString();
        string myString = (string)mac2.returnMyObject();
        DateTime myObject = (DateTime) mac1.returnMyObject();

        object obj1 = mac1.returnMyObject();
        object obj2 = mac2.returnMyObject();

        myMethod(obj1);  //---> This is not compiling
        myMethod(obj2);  //---> This is not compiling

        myMethod(myString);  //---> works fine
        myMethod(myObject);  //---> works fine

        Console.ReadKey();
    }
    public static void myMethod(DateTime dt)
    {
    }
    public static void myMethod(string st)
    {
    }
}
abstract class myAbstarctClass
{
    protected string mMyString;
    public myAbstarctClass()
    {
        mMyString = "myAbstarctClass ";
    }
    public abstract void changeMyString();
    public abstract object returnMyObject();        
}

class MyNewAbstractClass1 : myAbstarctClass
{
    DateTime mObject;
    public MyNewAbstractClass1(string myString)
    {
        mMyString = myString;
        mObject = new DateTime().Date;
    }
    public override void changeMyString()
    {
        mMyString += " MyNewAbstractClass1";
        Console.WriteLine(mMyString);
    }
    public override object returnMyObject()
    {
        return mObject;
    }
}

class MyNewAbstractClass2 : myAbstarctClass
{
    string mString;
    public MyNewAbstractClass2(string myString)
    {
        mMyString = myString;
        mString = mMyString;
    }
    public override void changeMyString()
    {
        mMyString += " MyNewAbstractClass2";
        Console.WriteLine(mMyString);
    }
    public override object returnMyObject()
    {
        return mString;
    }
}

static class ObjectFactory
{
    public static myAbstarctClass ObjectCreator(string myString)
    {
        switch (myString)
        {
            case "aaa":
                return new MyNewAbstractClass1(myString);
            case "bbb":
                return new MyNewAbstractClass2(myString);
            default:
                return null;
        }
    }
}    
}

我的问题是在 Main() 中我不知道 returnMyObject() 方法返回什么类型,所以我无法将它发送到 MyMethod。有没有办法投射物体?

4

6 回答 6

5

因为在你的设计中returnMyObject()你回到了最常见的object参考,你必须在运行时找出:

if (obj1 is string)
     myMethod((string)obj1);  //--->cast it 
else if (obj1 is DateTime)
     myMethod((DateTime) obj1);
于 2010-08-05T12:21:23.520 回答
4

您可以在运行时检查对象的类型:

公共静态无效我的方法(对象o)
{
    如果(o 是日期时间)
        我的方法((日期时间)o);
    else if (o 是字符串)
        我的方法((字符串)o);
}

尽管在您的情况下,您最好将myAbstarctClass实例传递给myMethod,然后returnMyObject()在那里调用。

于 2010-08-05T12:22:07.157 回答
1

使用多态机制,因此您不需要知道对象的类型。

在和中myMethod创建抽象方法myAbstarctClass并提供实现。MyNewAbstractClass1MyNewAbstractClass2

修改myAbstractClass1.returnMyObject()为返回myAbstarctClass(不是object)。

Main然后可以编写中的测试代码:

...
myAbstarctClass obj1 = mac1.returnMyObject();
myAbstarctClass obj2 = mac2.returnMyObject();

obj1.myMethod();        // calls MyNewAbstractClass1.myMethod()
                        // no if statement required!

obj2.myMethod();        // calls MyNewAbstractClass2.myMethod()
                        // no if statement required!

Console.ReadKey();

编辑:这可以进一步简化,因为returnMyObject()不再需要这些方法 - 它们只是返回您已经拥有的对象。测试代码现在很简单:

mac1.myMethod();
mac2.myMethod();

// etc...
Console.ReadKey();
于 2010-08-06T00:05:36.057 回答
1

您可以使用 C# 4.0 中的动态功能或更改设计以利用某种双重调度技术

        dynamic obj1 = mac1.returnMyObject();
        dynamic obj2 = mac2.returnMyObject();
于 2010-08-05T12:22:55.080 回答
0

不,您必须创建具有所有可能性的开关,或者类似的东西Dictionary<Type, Delegate>

或者你可以只做 myMethod(object obj)

它被称为多重调度(http://en.wikipedia.org/wiki/Multiple_dispatch)并且有一些库可以做到这一点

于 2010-08-05T12:22:46.503 回答
0

由于您似乎将您的类用作类型(例如DateTimestring)的容器,因此泛型可能比继承更好:

namespace CheckAbstract
{
    class Program
    {
        static void Main(string[] args)
        {
            myTemplateClass<DateTime> mac1 = new myTemplateClass<DateTime>(new DateTime().Date);
            myTemplateClass<string> mac2 = new myTemplateClass<string>("cat dog");

            mac1.changeMyString();
            mac2.changeMyString();
            string myString = (string)mac2.returnMyObject();
            DateTime myObject = (DateTime) mac1.returnMyObject();

            myMethod<string>(myString);
            myMethod<DateTime>(myObject);

            Console.ReadKey();
        }

        public static void myMethod<T>(T obj)
        {
        }
    }

    class myTemplateClass<T>
    {
        T mObject;
        string mMyString;
        public myTemplateClass(T init)
        {
            mMyString = init.ToString();
            mObject = init;
        }
        public void changeMyString()
        {
            mMyString += " " + mObject.ToString();
            Console.WriteLine(mMyString);
        }
        public T returnMyObject()
        {
            return mObject;
        }
    }
}
于 2010-08-08T09:49:41.633 回答