DaveG
DaveG

Reputation: 501

Make instance of "object" to other class and call method

I want to define an object and make instance of it to other class, but I can't call the method, here's my code:

    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 know there's a way of creat an interface I_Test, and do this:

class Test1:I_Test 
class Test2:I_Test

but since class Test2 is a dll from third-party so I can't add :I_Test to it, so I want to make my code here achievable, any suggestion? thx!

Upvotes: 0

Views: 102

Answers (4)

Arad
Arad

Reputation: 12851

You can do these two solutions to solve this problem: 1. Convert a to the class that you want and then you can call the method: Try this:

    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. use dynamic keyword instead of object type. Try this:

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

Upvotes: 1

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

If you are using the C# 7 you can use the new syntax that allows you to test and put the result of the test into a variable in a single line :

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

If you are using older C# you can use the as operator coupled with a null test :

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

You can also use a test and cast solution which minimizes the amount of variables, this is not recommended as that may forces the runtime to test twice (once for is and once for the cast). See this question for a more detailed response

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

Upvotes: 1

John Wu
John Wu

Reputation: 52290

Let's say you have a third party DLL that contains a class...

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

And you want to create your own class that has a method or property in common with the third party class:

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

As you mention, what you'd normally do is add an interface to the third party class, and then implement that interface in your own class. But you can't do that, as you also pointed out. And without an interface in common, you're stuck with that clunky if/then construct.

If I correctly understand your situation, you can deal with it as follow. Extend the third party class to add the interface, like so:

interface IMyInterface
{
    bool Foo { get; }
}

class MyThirdPartyClass : ThirdPartyClass, IMyInterface
{
}

Since Foo is public, it will get inherited and be available, and satisfy the interface. And now you can create your own class too:

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

And you can use them interchangeably:

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

That's how I would do it.

You may run into a problem if the third party class is sealed. If that is the case, you have to wrap it instead of inheriting from it:

class MyThirdPartyClassWrapper : IMyInterface
{
    private readonly ThirdPartyClass _wrappedInstance = new ThirdPartyClass();

    public bool Foo { get { return _wrappedInstance.Foo; } }
}

And then it'll still work:

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

Upvotes: 0

FCin
FCin

Reputation: 3925

You have to cast it first

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

Or older way of doing this:

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

Upvotes: 0

Related Questions