C# Eventhandler:发送方强制转换与反射
我有一个可能很简单的问题,但我的知识并不能掩盖为什么我会有以下代码的不同行为:C# Eventhandler:发送方强制转换与反射,c#,reflection,casting,C#,Reflection,Casting,我有一个可能很简单的问题,但我的知识并不能掩盖为什么我会有以下代码的不同行为: private void Test_ResultStateChangedEventHandler(object sender, EventArgs e) { Testcases.AbstractTestCase tc = (Testcases.AbstractTestCase)sender; System.Reflection.MethodInfo mInfo = sender.GetType().
private void Test_ResultStateChangedEventHandler(object sender, EventArgs e)
{
Testcases.AbstractTestCase tc = (Testcases.AbstractTestCase)sender;
System.Reflection.MethodInfo mInfo = sender.GetType().BaseType.GetMethod("get_TestResult");
object retval = mInfo.Invoke(sender, new object[] { });
if (retval != tc.TestResult)
throw new ArgumentException(); // Just to get a hold
}
我得到了抽象基类AbstractTestCase,其中属性TestResult在运行时被更改
初始值为“未定义”,其更改不应引发ResultStateChangedEventHandler。到目前为止还可以
如果我更改了结果状态,那么我希望它是“未测试的”。测试启动后(在将值设置为“not_tested”的初始化之后紧随其后),此属性立即设置为“running”,从而引发事件
现在我得到了两个不同的结果,这取决于我是通过反射访问这个Abstract类,还是simpyl将发送者转换为AbstractTestCase类类型
虽然反射按预期提供“未测试”,但直接强制转换将提供“正在运行”,即使调试器的单个步骤也表示“未测试”
值得一提的是,testcase正在另一个线程中运行,因此我假设在访问它的属性之前,该值已经被更改了
这让我感到困惑的原因是,我认为反射比我通过将发送者强制转换到tc变量创建的实例引用慢得多
我更喜欢使用cast而不是反射,因为访问类成员需要一大堆代码
我的错在哪里?如果反射较慢,为什么我的演员比反射较慢?谢谢:)
编辑1:更多的代码
_tcMngr只不过是一个类集合,允许动态运行不同的测试用例,并由伪类提供。Eventhandler和下面的代码正在UI线程中运行。AbstractTestCase正在新线程中运行
在UI线程中,Being启动了测试:
_tcMngr.Initialize(identifier);
var t = Task.Factory.StartNew(() =>
{
_tcMngr.RunSingle(identifier);
});
这是在运行时设置的属性:
public abstract class AbstractTestCase : TestReport, IStdTestCase
{
public delegate void StatusChangedEventHandler(object sender, StatusChangedEventArgs e);
public event StatusChangedEventHandler StatusChanged;
protected virtual void OnStatusChanged(StatusChangedEventArgs e)
{
if (StatusChanged != null)
StatusChanged(this, e);
}
protected virtual void ReportProgress(int percentage, string step, int maxPercentage = 100)
{
OnStatusChanged(new StatusChangedEventArgs()
{
Percentage = percentage,
Step = step,
MaxPercentage = maxPercentage
});
}
public class StatusChangedEventArgs : EventArgs
{
public int Percentage { get; set; } = 0;
public int MaxPercentage { get; set; } = 100;
public string Step { get; set; } = "";
}
public abstract void Run();
public abstract void Dispose();
public abstract string ShortDescription {
get;
}
public virtual int EstimatedRuntime { get; } = 100;
public abstract override string ToString();
public abstract void Initialize();
public int Identifier { get; set; }
}
public abstract class TestReport {
public enum TestCaseResultStates
{
Running = 2,
Success = 1,
Fail = 0,
Undefined = -1,
NotTested = int.MaxValue
}
TestCaseResultStates _testresult = TestCaseResultStates.Undefined;
public TestCaseResultStates TestResult
{
get
{
return _testresult;
}
set
{
_testresult = value;
OnResultStateChanged(null);
}
}
}
这是一个用于调试的虚拟测试用例:
public class Dummy : AbstractTestCase
{
public override string ShortDescription
{
get
{
return "Dummy for debugging.";
}
}
public override void Dispose()
{
// nothing to do here
}
public override void Initialize()
{
base.TestResult = TestCaseResultStates.NotTested;
}
public override void Run()
{
base.TestResult = TestCaseResultStates.Running;
for (int i = 1; i < 11; i++)
{
System.Threading.Thread.Sleep(1000);
base.ReportProgress(i * 10, "Step " + i + " / 10");
}
base.TestResult = TestCaseResultStates.Fail;
base.TextResult = "Test was finished: \"" + base.TestResult.ToString() + "\"";
}
public override string ToString()
{
return "Dummy";
}
public override int EstimatedRuntime
{
get
{
return 10;
}
}
}
公共类伪:AbstractTestCase
{
公共重写字符串简短描述
{
得到
{
返回“Dummy for debug.”;
}
}
公共覆盖无效处置()
{
//这里没什么可做的
}
公共覆盖无效初始化()
{
base.TestResult=testcasesultstates.NotTested;
}
公共覆盖无效运行()
{
base.TestResult=testcasesultstates.Running;
对于(int i=1;i<11;i++)
{
系统线程线程睡眠(1000);
基本进度报告(i*10,“步骤”+i+“/10”);
}
base.TestResult=testcasesultstates.Fail;
base.TextResult=“测试已完成:\”“+base.TestResult.ToString()+”\”;
}
公共重写字符串ToString()
{
返回“Dummy”;
}
公共覆盖整数估计时间
{
得到
{
返回10;
}
}
}
因此您有两个不同的线程:一个线程正在使用testcase执行某些操作(可能正在更改其状态),另一个线程调用事件?闻起来像是线程竞赛。或者不使用Type.GetProperty()的一些奇怪的结果。当你不给我们看房子的样子时,那只是瞎猜,没有意义。嗯。。我将尝试添加一些更相关的代码,但事实上没有这么多。请使用调试器。在TestResult属性设置器上设置一个断点,堆栈跟踪告诉您是什么代码更改了它的值。此值更改将引发事件,我希望反射比直接类型转换慢。我想知道为什么它不是完全相反的方式?然而,正如前面提到的,这种竞争条件可能会成为一个问题,因此我无论如何都要对我的代码做一些修改。