将"object"实例设置为其他类并调用方法



我想定义一个object并将其实例化为其他类,但是我无法调用该方法,这是我的代码:

    class Test1
    {
        public bool True_1()
        {return true;}
    }
    class Test2
    {
        public bool True_2()
        {return true;}
    }
    class MainClass
    {
        static void Main()
        {
            object a;
            bool flag = true; // or false

            if (flag)
                a = new Test1();
            else
                a = new Test2();

            if (a is Test1)
                a.True_1();        //error before compiling
            else
                a.True_2();        //error before compiling
        }
    }
}

我知道有一种创建接口I_Test的方法,并执行此操作:

class Test1:I_Test 
class Test2:I_Test

但是,由于Test2类是第三方的DLL,所以我无法向其添加:I_Test,所以我想在这里做我的代码,有什么建议吗?thx!

如果您使用的是C#7,则可以使用新的语法,使您可以测试并将测试结果放入一行中的变量:

if (a is Test1 aTest)
    aTest.True_1();
else if( a is Test2 aTest2)
    aTest2.True_2();

如果您使用的是较旧的C#,则可以使用 as运算符和无效测试:

var aTest = a as Test1;
if (aTest != null)
    aTest.True_1();
else
{
    var aTest2 = a as Test2;
    if (aTest2 != null)
    {
        aTest2.True_2();
    }
}

您还可以使用最小化变量量的测试和铸造解决方案,这不建议这样做,因为这可能会迫使运行时测试两次(一次用于is,一次用于铸件)。请参阅此问题,以获取更详细的回答

if(a is Test1) 
    ((Test1)a).True_1();

您可以执行这两个解决方案来解决此问题:1.将a转换为您想要的类,然后可以调用方法:尝试以下:

    static void Main()
    {
        object a;
        bool flag = true;

        if (flag)
            a = new Test1();
        else
            a = new Test2();

        if (a is Test1)
        {
            ((Test1)a).True_1();        //So, there will be no error anymore
        }
        else
        {
            ((Test2)a).True_2();
        }
    }
  1. 使用dynamic关键字代替object类型。尝试以下操作:

    static void Main()
    {
        dynamic a;
        bool flag = true;
    
        if (flag)
            a = new Test1();
        else
            a = new Test2();
    
        if (a is Test1)
            a.True_1();        //So, there will be no error anymore
        else
            a.True_2();
    }
    

您必须先施放它

if(a is Test1 aConverted) 
    aConverted.True_1();

或较早的方法:

if(a is Test1) 
    ((Test1)a).True_1();

假设您有一个包含类的第三方DLL ...

class ThirdPartyClass
{
    public bool Foo { get { return true;} }
}

您想创建自己的类,该类具有与第三方类共同的方法或属性:

class MyClass
{
    public bool Foo { get { return true;} }
}

您提到的是,您通常要做的就是在第三方类中添加接口,然后在您自己的类中实现该界面。但是,正如您还指出的那样,您不能这样做。如果/构造,没有一个共同的界面,您就会陷入困境。

如果我正确理解您的情况,则可以按照以下方式处理。扩展第三方类以添加界面,例如:

interface IMyInterface
{
    bool Foo { get; }
}
class MyThirdPartyClass : ThirdPartyClass, IMyInterface
{
}

由于Foo是公开的,因此它将被继承和可用,并满足界面。现在您也可以创建自己的课程:

class MyClass : IMyInterface
{
    public bool Foo { get { return true; }}
}

您可以互换使用它们:

IMyInterface a = new MyThirdPartyClass();
IMyInterface b = new MyClass();
bool c = a.Foo; 
bool d = b.Foo;

这就是我的方式。

如果密封第三方类,您可能会遇到问题。如果是这种情况,则必须包裹它而不是从中继承:

class MyThirdPartyClassWrapper : IMyInterface
{
    private readonly ThirdPartyClass _wrappedInstance = new ThirdPartyClass();
    public bool Foo { get { return _wrappedInstance.Foo; } }
}

然后它仍然有效:

IMyInterface a = new MyThirdPartyClassWrapper();
IMyInterface b = new MyClass();
bool c = a.Foo; 
bool d = b.Foo;

相关内容

最新更新