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

実行時にオブジェクトのタイプを確認できます。

public static void myMethod(Object o)
{
    if (o は DateTime)
        myMethod((DateTime)o);
    else if (o は文字列)
        myMethod((文字列)o);
}

あなたの場合は、myAbstarctClassインスタンスをに渡してからmyMethod、そこで呼び出すreturnMyObject()こともできます。

于 2010-08-05T12:22:07.157 に答える
1

オブジェクトのタイプを知る必要がないように、ポリモーフィズム メカニズムを使用します。

の抽象myMethodメソッドを作成し、 と の両方でmyAbstarctClass実装を提供します。MyNewAbstractClass1MyNewAbstractClass2

(not )myAbstractClass1.returnMyObject()を返すように変更します。myAbstarctClassobject

のテスト コードは次の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 に答える