有没有办法在C#中编写二进制文字,比如用0x前缀十六进制?0b不起作用.
如果没有,有什么简单的方法可以做到这一点?某种字符串转换?
我需要使用很久以前在Delphi中开发的COM组件(dll).问题是:dll不包含类型库...并且.NET中的每个互操作功能(例如,TlbImp)似乎都依赖于TLB.这个组件已经在Delphi程序中使用了很多年没有问题,因为"使用Delphi的COM对象并不是什么问题,因为我们知道接口"(引用Delphi开发人员).
有没有办法在没有TLB的情况下从c#中使用这个DLL?我已经使用DLL作为未试过,但唯一的方法是出口DllUnregisterServer,DllRegisterServer,DllCanUnloadNow和DllGetClassObject.我知道我将要使用的类和函数的名称,如果这可以有任何帮助.
更新: 我已经尝试过实施Jeff的建议,但是我收到了这个错误:
"无法将'ComTest.ResSrvDll'类型的COM对象强制转换为接口类型'ComTest.IResSrvDll'.此操作失败,因为对于具有IID'{75400500-939F-11D4-9E44-0050040CE72C}的接口的COM组件上的QueryInterface调用'由于以下错误而失败:不支持此类接口(来自HRESULT的异常:0x80004002(E_NOINTERFACE))."
这就是我所做的:
我从其中一个Delphi人那里得到了这个接口定义:
unit ResSrvDllIf;
interface
type
IResSrvDll = interface
['{75400500-939F-11D4-9E44-0050040CE72C}']
procedure clearAll;
function ResObjOpen(const aClientID: WideString; const aClientSubID: WideString;
const aResFileName: WideString; aResShared: Integer): Integer; {safecall;}
...
end;
implementation
end.
Run Code Online (Sandbox Code Playgroud)
从这个我做了这个界面
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400500-939F-11D4-9E44-0050040CE72C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IResSrvDll
{
int ResObjOpen(string aClientID, string aClientSubID, string aResFileName, int aResShared);
}
}
Run Code Online (Sandbox Code Playgroud)
而这个coclass(得到了德尔福人的指导)
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400503-939F-11D4-9E44-0050040CE72C")]
public class ResSrvDll
{
} …Run Code Online (Sandbox Code Playgroud) 我一直在寻找复合应用程序库,它很棒,但我无法决定何时使用EventAggregator ......或者更确切地说 - 当不使用它时.
看看StockTraderRI的例子,我更加困惑.他们在某些情况下使用EventAggregator,在其他情况下使用"经典"事件(例如在IAccountPositionService接口中).
我已经决定使用它来处理繁重的工作任务,这应该在后台线程上运行.在这种情况下,EventAggregator在幕后提供线程编组,所以我不必担心这一点.除此之外,我喜欢这种方法提供的解耦.
所以我的问题是:当我开始在我的应用程序中使用EventAggregator时,为什么不将它用于所有自定义事件?
我想对我所创建的类进行单元测试,但是这种方法需要先调用另一种方法.例:
// This would work
MyClass myClass1 = new MyClass(mockDevice);
myClass1.Run(myDatastructure);
myClass1.Stop();
// This would throw an InvalidOperationException
MyClass myClass2 = new MyClass(mockDevice);
myClass2.Stop();
Run Code Online (Sandbox Code Playgroud)
Run正在硬件设备上启动操作Stop,当然是尝试停止该操作(发送reset-command并启动timeout-timer).
无论如何,我想测试各种调用的后置条件Stop,但我不想打电话Run,因为我正在测试Stop- 不是Run!我想要这样的东西:
MyClass myClass = new MyClass(mockDevice);
myClass.Stop();
Assert.IsTrue(mockDevice.ResetCalled);
Run Code Online (Sandbox Code Playgroud)
到目前为止,我只看到一个可能的解决方案,那就是创建一个TestableMyClass继承自的方法MyClass,这样就可以MyClass在调用之前设置实例的正确内部状态Stop.这个解决方案的问题是我必须改变我的MyClass实现以保护成员而不是私有成员,我不喜欢为了测试它而不得不改变实现的想法!
我应该使用这个解决方案吗,我的设计中是否有错误,或者有更聪明的方法吗?
我有一个包含这样的异步调用的方法:
public void MyMethod() {
...
(new Action<string>(worker.DoWork)).BeginInvoke(myString, null, null);
...
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Unity 并且创建模拟对象不是问题,但是如何测试 DoWork 被调用而不必担心竞争条件?
一个先前的问题提供了解决方案,但在我看来,等待句柄是一个黑客(比赛条件仍然存在,尽管它应该是几乎不可能提高)。
编辑:好的,我想我可以以非常笼统的方式问这个问题,但似乎我必须进一步详细说明这个问题:
我想为上面提到的 MyMethod 创建一个测试,所以我做这样的事情:
[TestMethod]
public void TestMyMethod() {
...setup...
MockWorker worker = new MockWorker();
MyObject myObj = new MyObject(worker);
...assert preconditions...
myObj.MyMethod();
...assert postconditions...
}
Run Code Online (Sandbox Code Playgroud)
最简单的方法是创建一个 MockWorker(),它在调用 DoWork 时简单地设置一个标志,并在后置条件中测试该标志。这当然会导致竞争条件,即在 MockWorker 中设置标志之前检查后置条件。
更正确的方法(我可能最终会使用)是使用等待句柄:
class MockWorker : Worker {
public AutoResetEvent AutoResetEvent = new AutoResetEvent();
public override void DoWork(string arg) {
AutoResetEvent.Set();
}
}
Run Code Online (Sandbox Code Playgroud)
...并使用以下断言:
Assert.IsTrue(worker.AutoResetEvent.WaitOne(1000, false));
Run Code Online (Sandbox Code Playgroud)
这是使用类似信号量的方法,这很好……但理论上可能会发生以下情况:
我在单元测试期间遇到了一个非常奇怪的问题(Visual Studio中的MSTest - .NET 3.5 SP1):
正如您所看到的,问题非常不一致,使调试变得困难.
我尝试过使用Fusion Log Viewer,但这让我感到困惑,我不太明白.
我应该寻找什么?还有其他人遇到过这个问题吗?
更新: 请求了一些其他信息.
测试运行好几个月 - 我认为上次运行它们是星期四,然后它们运行良好.我一直试图检查源代码控制历史,看看是否有变化,但没有任何异常.
我可以追溯并在不同的日子检查项目,但我们正在使用Visual Source Safe(我知道 - 不是我的descission :-()所以我很犹豫这样做.
测试是常规的单元测试,我使用Moq作为模拟对象...但正如我所说 - 它直到最近一直运行良好.
我只是希望就如何调试此问题提供一些建议.
我已经为基于密钥的字符串翻译做了标记扩展.例
<TextBlock Text="{Translate myKey}" />
Run Code Online (Sandbox Code Playgroud)
现在我希望能够使用嵌套绑定来提供我的密钥.例:
<TextBlock Text="{Translate {Binding KeyFromDataContext}}" />
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我得到一个System.Windows.Data.Binding对象.通过调用ProvideValue并传递ServiceProvider,我可以得到一个BindingExpression:
var binding = Key as Binding;
if (binding == null) {
return null;
}
var bindingExpression = binding.ProvideValue(_serviceProvider) as BindingExpression;
if (bindingExpression == null) {
return null;
}
var bindingKey = bindingExpression.DataItem;
Run Code Online (Sandbox Code Playgroud)
我可以得到这个bindingExpression,但DataItem属性为null.我已经像这样测试了我的绑定
<TextBlock Text="{Binding KeyFromDataContext}" />
Run Code Online (Sandbox Code Playgroud)
它工作正常.
有任何想法吗?
c# ×7
unit-testing ×2
.net ×1
binary ×1
com ×1
concurrency ×1
data-binding ×1
delphi ×1
events ×1
interop ×1
mstest ×1
prism ×1
syntax ×1
wpf ×1