多态和铸造问题

发布于 2024-09-13 04:31:31 字数 2430 浏览 11 评论 0原文

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

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。有没有办法铸造物体?

In order to explain my problem here is an example

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;
        }
    }
}    
}

My problem is that in Main() I don't know what type the returnMyObject() method returns so I can't send it to MyMethod. Is there a way to cast the objects ??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

神回复 2024-09-20 04:31:31

因为在您的 returnMyObject() 设计中,您回到了最常见的 object 引用,因此您必须在运行时找出:

if (obj1 is string)
     myMethod((string)obj1);  //--->cast it 
else if (obj1 is DateTime)
     myMethod((DateTime) obj1);

Because in your design of returnMyObject() you went back to the most common object references, you will have to find out in runtime:

if (obj1 is string)
     myMethod((string)obj1);  //--->cast it 
else if (obj1 is DateTime)
     myMethod((DateTime) obj1);
依 靠 2024-09-20 04:31:31

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

public static void myMethod(Object o)
{
    if (o is DateTime)
        myMethod((DateTime)o);
    else if (o is string)
        myMethod((string)o);
}

尽管在您的情况下,您也可以将 myAbstarctClass 实例传递给 myMethod,然后调用 returnMyObject()< /代码> 那里。

You could check the object's type at runtime:

public static void myMethod(Object o)
{
    if (o is DateTime)
        myMethod((DateTime)o);
    else if (o is string)
        myMethod((string)o);
}

Although in your case, you might just as well pass a myAbstarctClass instance to myMethod, and then call returnMyObject() there.

韶华倾负 2024-09-20 04:31:31

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

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

You can either use dynamic feature from C# 4.0 or change design to utilize some kind of double dispatch technique

        dynamic obj1 = mac1.returnMyObject();
        dynamic obj2 = mac2.returnMyObject();
猫性小仙女 2024-09-20 04:31:31

使用多态机制,这样您就不需要知道对象的类型。

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();

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

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

// etc...
Console.ReadKey();

Use Polymorphism mechanisms so you don't need to know the type of object.

Make myMethod an abstract method of myAbstarctClass and provide implementations in both MyNewAbstractClass1 and MyNewAbstractClass2.

Modify myAbstractClass1.returnMyObject() to return myAbstarctClass (not object).

The test code in Main can then be written:

...
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();

Edit: This can be further simplified, since the returnMyObject() methods are no longer necessary - they just return the object you already have. The test code is now simply:

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

// etc...
Console.ReadKey();
递刀给你 2024-09-20 04:31:31

不,您必须创建具有所有可能性的 switch,或者类似 Dictionary 的东西,

或者您可以将 myMethod(object obj)

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

No, you have to either create switch with all possibilities, or something like Dictionary<Type, Delegate>

or you can just make myMethod(object obj)

it's called Multiple dispatch (http://en.wikipedia.org/wiki/Multiple_dispatch) and there are some libraries that can do it

橘虞初梦 2024-09-20 04:31:31

由于您似乎使用类作为类型的容器(例如 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;
        }
    }
}

Since you seem to be using your class as a container for a type (eg. DateTime, string), perhaps Generics would a be better choice than Inheritance:

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文