将“对象”的实例设为其他类和调用方法

时间:2017-12-11 07:17:39

标签: c# instance

我想定义一个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!

4 个答案:

答案 0 :(得分:1)

如果您使用的是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,一次用于强制转换)。有关更详细的回复,请参阅此question

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

答案 1 :(得分: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();
    }
    

答案 2 :(得分:0)

你必须先施展它

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

或者更老的方式:

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

答案 3 :(得分:0)

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

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

并且您希望创建自己的类,该类具有与第三方类共有的方法或属性:

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

正如您所提到的,您通常要做的是向第三方类添加接口,然后在您自己的类中实现该接口。但你也不能这样做,正如你也指出的那样。如果没有共同的界面,你就会坚持使用那种笨重的if / then构造。

如果我正确理解您的情况,您可以按照以下方式处理。扩展第三方类以添加接口,如下所示:

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;

我就是这样做的。

如果第三方课程为sealed,您可能会遇到问题。如果是这种情况,你必须包装它而不是从它继承:

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;