我想定义一个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!
答案 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();
}
}
使用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;