几年来我一直是一位势在必行的开发人员,我从未有过学习函数式编程的冲动.
几个月前,我终于决定学习Haskell.这是一个非常酷的语言,但我很困惑如何用这种语言编写一个事件驱动的真实应用程序.你知道一个关于它的好教程吗?
注意:当我说"真正的应用程序"时,我不是在谈论现实世界,生产就绪应用程序.我只是说一个小样本应用程序,只是为了掌握它.我觉得像windows caculator的简化版本会很棒,然后可能会更复杂一点.
在C++中不可能声明静态虚函数,也不能将非静态函数强制转换为C样式函数指针.
现在,我有一个简单的ol'C SDK,它大量使用函数指针.
我必须用几个函数指针填充一个结构.我计划使用一个带有一堆静态纯虚方法的抽象类,并在派生类中重新定义它们并用它们填充结构.直到那时我才意识到在C++中不允许使用静态虚拟.
此C SDKs函数签名也没有userData参数.
有什么好的选择吗?我能想到的最好的方法是在每个派生类中定义一些纯虚方法GetFuncA(),GetFuncB(),...和一些静态成员FuncA()/ FuncB(),它们将由GetFuncX()返回.然后抽象类中的函数将调用这些函数来获取指针并填充结构.
编辑 回答John Dibling,能够做到这一点真是太好了:
class Base
{
FillPointers() { myStruct.funA = myFunA; myStruct.funB = myFunB; ...}
private:
CStruct myStruct;
static virtual myFunA(...) = 0;
static virtual myFunB(...) = 0;
};
class Derived1 : public Base
{
Derived1() { FillPointers(); }
static virtual myFunA(...) {...};
static virtual myFunB(...) {...};
};
class Derived2 : public Base
{
Derived2() { FillPointers(); }
static virtual myFunA(...) {...};
static virtual myFunB(...) {...};
};
int main()
{
Derived1 d1; …Run Code Online (Sandbox Code Playgroud) 我正在使用LoadWithPartialName()加载程序集,但VS告诉我它已过时并使用Load()代替.但是,我找不到任何方便的过载.
有一个Load(字符串)请求"全名",如果我理解正确的MSDN文档,包括版本号之类的东西.
还有一个Load(string,Evidence)接受"显示名称".问题是我没有丝毫知道"显示名称"是什么,因为我使用第一个功能的"部分名称"似乎不起作用.
那么,应该怎么做呢?
我发现了几个关于同一主题的问题,但与一般变量(值和引用类型)有关.这个问题的接受答案是:
CLI规范第12.6.6节的分区I指出:"符合要求的CLI应保证当对位置的所有写入访问的大小相同时,对不大于本机字大小的正确对齐的内存位置的读写访问权限是原子的. ".
引用变量(即类)是指针,等于本机字大小,但我有几个疑问:
参考是否保证在正确对齐的内存位置?
我不明白最后一部分.这是什么意思?"......当对一个位置的所有写访问都是相同的大小时."
简而言之,obj2保证在以下代码的循环的每次迭代中都有效吗?
class MyClass
{
private OtherClass m_Object;
void Thread1()
{
while(true)
{
OtherClass obj1 = new OtherClass();
m_Object = obj1;
}
}
void Thread2()
{
while (true)
{
OtherClass obj2 = m_Object;
// Is obj2 guaranteed to be valid?
obj2.Check();
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用来自第三方库的COM对象来生成定期事件.当我使用Winforms应用程序中的库,将对象作为类成员并在主窗体线程中创建它时,一切正常.但是,如果我从另一个线程创建对象,我不会收到任何事件.
我的猜测是我需要在用于创建对象的同一个线程中有某种事件循环.
我需要从控制台应用程序中使用此对象.我想我可以使用Application.DoEvents,但我宁愿不在控制台App中包含Winforms命名空间.
我怎么解决这个问题?
更新3(2011-06-15):供应商终于回答了.简而言之,他们说Application.Run创建的消息泵与Thread.Join创建的消息泵之间存在一些差异,但他们不知道这有什么区别.
我同意他们; 任何关于此事的光明都会非常感激.
更新:
从理查德评论到mdm回答:
如果其他组件是单线程并从MTA实例化,则Windows将创建工作线程+窗口+消息泵并执行必要的编组.
试着听从他的建议,我正在做以下事情:
更新2:
我改变了JoãoAngelo回答后的代码.
using System;
namespace ConsoleApplication2
{
class Program
{
[STAThread]
static void Main(string[] args)
{
MyComObjectWrapper wrapper = new MyComObjectWrapper();
}
}
class MyComObjectWrapper
{
MyComObject m_Object;
AutoResetEvent m_Event;
public MyComObjectWrapper()
{
m_Event = new System.Threading.AutoResetEvent(false);
System.Threading.Thread t = new System.Threading.Thread(() => CreateObject());
t.SetApartmentState (System.Threading.ApartmentState.STA);
t.Start();
Wait();
}
void ObjectEvt(/*...*/)
{
// ...
}
void Wait()
{
m_Event.WaitOne();
}
void CreateObject()
{
m_Object = new MyComObject();
m_Object.OnEvent …Run Code Online (Sandbox Code Playgroud) 我开始用C#2.0编程,所以我从未使用过lambda表达式,但是,为什么这么大惊小怪?它们只是围绕匿名代表的语法糖,还是还有一些我看不到的东西?
我之后,说
Foo* array = new Foo[N];
我总是这样删除它
delete[] array;
但是,有时候我这样看过:
delete[N] array;
由于它似乎在编译和工作(至少在msvc2005中),我想知道:正确的方法是什么?为什么它以其他方式编译呢?
我需要复制一行来改变PK.每个客户端安装中的表可以不同,因此我不能只列举列.我设法做了以下事情:
INSERT INTO table SELECT * FROM table WHERE PK='value'
Run Code Online (Sandbox Code Playgroud)
但显然它失败了,因为我试图复制PK.
然后我尝试了:
INSERT INTO table SELECT 'newValue' AS PK, * FROM table WHERE PK='value'
Run Code Online (Sandbox Code Playgroud)
它也失败了,因为列名不匹配.
我知道PK将永远是第一列,但我不确定它有多大用处.
那么......这可能吗?任何的想法?
我有一个XML文档,类似于
<root>
<item>_x0034_SOME TEXT</item>
<item>SOME_x0020_TEXT</item>
<item>SOME_x0020_TEXT_x0032_</item>
</root>
Run Code Online (Sandbox Code Playgroud)
我将它导出为HTML,但我在替换转义字符时遇到问题.我在网上找到了几个模板来进行文本替换,但它们都与此类似:
<xsl:template name="replaceString">
<xsl:param name="strOrig"/>
<xsl:param name="strSearch"/>
<xsl:param name="strReplace"/>
<xsl:choose>
<xsl:when test="contains($strOrig, $strSearch)">
<xsl:value-of select="substring-before($strOrig, $strSearch)"/>
<xsl:value-of select="$strReplace"/>
<xsl:call-template name="replaceString">
<xsl:with-param name="strOrig" select="substring-after($strOrig, $strSearch)"/>
<xsl:with-param name="strSearch" select="$strSearch"/>
<xsl:with-param name="strReplace" select="$strReplace"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$strOrig"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
我不知道如何使用它来进行多次替换.我试过这个:
<xsl:for-each select="PinnacleSys.PMC.Plugins.PVR.PvrChannelDescriptorWrapper/PinnacleSys.PMC.Plugins.PVR.DVBTPvrChannelDescriptor">
<!--name="<xsl:value-of select="replace(replace(Name, '_x0020_', ' '), '_x0034_', '3')"/>" -->
<!--name="<xsl:value-of select="Name"/>"-->
<xsl:variable name="var1" select="Text" />
<xsl:value-of select="replace($FeatureInfo,'Feature=','TESTING')"/>
name="
<xsl:call-template name="replaceString">
<xsl:with-param name="strOrig" select="Name"/>
<xsl:with-param name="strSearch" select="'_x0020_'"/>
<xsl:with-param name="strReplace" select="' '"/>
</xsl:call-template>
<xsl:call-template name="replaceString"> …Run Code Online (Sandbox Code Playgroud) 我有一个BaseClass,一个DerivedClass1和一个来自第三方库的DerivedClass2.DerivedClass1和DerivedClass2都从BaseClass继承.
有一个来自同一个库的ContainerClass,它有一个成员变量ActiveItem,它可以是DerivedClass1或DerivedClass2,所以它被声明为BaseClass.
我想知道ActiveItem是否属于DerivedClass1,因为它可以在运行时更改,恕不另行通知.
如果我做
Dim isDerivedClass1 as boolean = TypeOf(oject.ActiveItem) Is DerivedClass1
Run Code Online (Sandbox Code Playgroud)
然后我得到一个编译时错误,告诉我ActiveItem永远不能是DerivedClass1类型.
我尝试了几种GetType和TypeOf的组合,但似乎无法检查这一点.我还尝试声明一个辅助DerivedClass1变量并比较它们的类型,但也没有任何运气.
有没有解决方法?我想我可以用反射来做,但看起来真的有点矫枉过正.
编辑: 以下代码无法在vs2005 SP1中编译.
Public Class Base
Public x As Integer
End Class
Public Class Derived1
Inherits Base
Public y As Integer
End Class
Public Class Derived2
Inherits Base
Public z As Integer
End Class
Public Class Unrelated
Public var As Base
End Class
Public Class Form1
Public Sub Test(ByVal obj As Unrelated)
Dim tst As Boolean
tst = TypeOf obj Is Derived1
End Sub
Private …Run Code Online (Sandbox Code Playgroud)