我试图设置一个嵌套在另一个类中的值。有很多层次,这让我开始困惑,我需要第二个(或第三个)意见。
底部的两个命名类是来自Ivi.Visa.Interop.dll(一个VISA通信库)的第三方类。我不能访问他们的源代码。
看起来是这样的:
测试:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Ivi.Visa.Interop;
namespace Testing
{
public partial class Test : Form
{
public Test()
{
InitializeComponent();
}
// This works
private void btn_Direct_Click(object sender, EventArgs e)
{
FormattedIO488 tmp = new FormattedIO488();
ResourceManager rm = new ResourceManager();
tmp.IO = (IMessage)rm.Open("VISA ADDRESS HERE");
tmp.IO.TerminationCharacterEnabled = true;
tmp.WriteString("*IDN?");
Console.Write(tmp.ReadString().Trim());
}
// This does not work
private void btn_Nested_Click(object sender, EventArgs e)
{
A tmp = new A();
Console.Write(tmp.SimpleTest());
}
}
}
父类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ivi.Visa.Interop;
namespace Testing
{
class A
{
public B tmp;
ResourceManager rm;
public string SimpleTest()
{
tmp = new B();
tmp.session = new FormattedIO488();
rm = new ResourceManager();
tmp.session.IO = (IMessage)rm.Open("VISA ADDRESS HERE");
// Reflection attempt, but does not find the property.
foreach (var prop in tmp.session.IO.GetType().GetProperties())
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(tmp.session.IO, null));
}
tmp.session.IO.TerminationCharacterEnabled = true;
tmp.session.WriteString("*IDN?");
return (tmp.session.ReadString().Trim());
}
}
}
子类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Testing
{
class B : A
{
public dynamic session;
}
}
FormattedIO488: IFormattedIO488
...
IMessage IO { get; set; }
...
IMessage: IBaseMessage
...
[DispId(1610743814)]
bool TerminationCharacterEnabled { get; set; }
...
问题:我想设置TerminationCharacterEnabled,但在运行时,系统找不到属性。它可以找到FormattedIO488。
我的反射是正确的吗?当涉及到访问类中的类中的属性时,我还有什么其他选择?
或者,有一个很好的反射的例子,像这样的情况?
这是正确的,你不能实例化一个接口,如IMessage,根据。net命名约定IMessage将是一个接口,而不是一个抽象类;这并没有多大区别,因为两者都不能被实例化,因为它们没有实现任何东西或所有东西,就像抽象类的情况一样。你需要声明一个类来实现这个接口。
public class MyMessage : IMessage
{
// ... everything that IMessage declares you implement.
}
然后你可以使用你的类实例化这个对象。
你可以不创建一个重复的类:
- 如果你能找到实现IMessage的对象。如果你在一个已经存在的对象上使用反射并复制这个对象,听起来可能就是这样,那么你可以找到这个对象的类型,看看它是否有一个公共构造函数。
- 使用一个模拟库来模拟接口…如果IMessage来自外部dll,并且在随后的更新期间可能会发生变化,那么mock将是一个合适的解决方案,否则我会远离在实时代码中使用mock,并坚持只模拟用于测试目的的对象。
无论如何-祝你好运!