假设我有一个自定义类(任何类)及其方法和属性:
public class Test
{
public string MyString { get; set; }
public bool MyBool { get; set; }
public override string ToString()
{
return "Test Class : " + this.MyString + " - " + MyBool;
}
}
现在我想使用VisualBasicValue<T>
在WF4活动之间移动和处理它的属性。例如:
public class Program
{
static void Main(string[] args)
{
Test testClass = new Test()
{
MyString = "some string",
MyBool = true
};
Sequence wf = new Sequence()
{
Variables =
{
new Variable<Test>("varName", testClass),
},
Activities =
{
new WriteLine() { Text = new VisualBasicValue<string>("\"Test Class Properties: \" & varName.MyString & \"-\" & varName.MyBool") },
new WriteLine() { Text = new VisualBasicValue<string>("\"Test Class ToString(): \" & varName") }
}
};
WorkflowInvoker.Invoke(wf);
Console.ReadKey();
}
}
此代码编译没有问题。变量可以处理任何类,但运行时它似乎抱怨自定义类的用法。一些例外,如:
The following errors were encountered while processing the workflow tree:
'Literal<Test>': Literal only supports value types and the immutable type System.String. The type WorkflowConsoleApplication3.Test cannot be used as a literal.
'VisualBasicValue<String>': Compiler error(s) encountered processing expression ""Test Class ToString(): " & varName".
运营商'&amp;'没有为类型'String'和'WorkflowConsoleApplication3.Test'定义。
我读过你可以这样做:
VisualBasicSettings vbSettings = new VisualBasicSettings();
vbSettings.ImportReferences.Add(new VisualBasicImportReference()
{
Assembly = typeof(Test).Assembly.GetName().Name,
Import = typeof(Test).Namespace
});
// construct workflow
VisualBasic.SetSettings(wf, vbSettings);
WorkflowInvoker.Invoke(wf);
但这似乎没有成功。有什么帮助吗?
PS:在同一个主题上,有人能给我一个例子,说明如何使用VisualBasicReference<T>' with
OutArgument`?这似乎是我可以在以后使用的东西,但我会找到任何一种例子。
答案 0 :(得分:1)
我进行了一些更改以使您的代码正常工作。
更正后的代码如下
private static void Main(string[] args)
{
var testClass = new Test { MyString = "some string", MyBool = true };
var wf = new Sequence
{
Variables = {
// Changed to use ActivityFunc so testClass is not interpreted as a literal
new Variable<Test>("varName", ctx => testClass),
},
Activities =
{
new WriteLine
{
Text =
new VisualBasicValue<string>(
"\"Test Class Properties: \" & varName.MyString & \"-\" & varName.MyBool")
},
// Changed to call ToString explicitly
new WriteLine { Text = new VisualBasicValue<string>("\"Test Class ToString(): \" & varName.ToString()") }
}
};
var settings = new VisualBasicSettings();
settings.ImportReferences.Add(
new VisualBasicImportReference
{
Assembly = typeof(Test).Assembly.GetName().Name, Import = typeof(Test).Namespace
});
// construct workflow
VisualBasic.SetSettings(wf, settings);
WorkflowInvoker.Invoke(wf);
Console.ReadKey();
}
还有一件事。有些人质疑为什么有必要使用VB Concat运算符显式调用Test.ToString()。这是一个奇怪的问题,它是C#中声明的类型与VB中声明的类型不同的地方之一。
C#使用+运算符进行加法和连接,其中VB具有&amp; concat的运算符和特定的IL指令op_Concat。
如果你在VB中声明你的类型,你可以重载&amp;运算符,以消除在表达式中调用ToString()的需要。
例如
Public Class Test
Public Property MyString As String
Public Property MyBool As Boolean
Public Overrides Function ToString() As String
Return "Test Class : " & MyString + " - " & MyBool
End Function
Public Shared Operator &(ByVal left As String, ByVal right As Test) As String
Return left & "-" & right.ToString
End Operator
End Class
当处理像VB这样的问题时,我经常只创建VB控制台应用程序以测试除Workflow之外的东西
Module Module1
Dim varName As New Test With {.MyBool = True, .MyString = "some string"}
Sub Main()
Console.WriteLine("Test Class Properties: " & varName.MyString & "-" & varName.MyBool)
Console.WriteLine("Test Class ToString(): " & varName)
Console.ReadKey()
End Sub
End Module
此应用程序发出的IL显示操作员
IL_002f: ldstr "Test Class ToString(): "
IL_0034: ldsfld class VBTest.Test VBTest.Module1::varName
IL_0039: call string VBTest.Test::op_Concatenate(string, class VBTest.Test)
IL_003e: call void [mscorlib]System.Console::WriteLine(string)
答案 1 :(得分:0)
以下代码有效。请注意我使用lambda而不是固定值初始化变量的方式,第二个VB表达式使用+而不是&amp ;.对我来说,最后一个看起来像个错误,我将跟进。
static void Main()
{
Test testClass = new Test()
{
MyString = "some string",
MyBool = true
};
Sequence wf = new Sequence()
{
Variables =
{
new Variable<Test>("varName", c => testClass),
},
Activities =
{
new WriteLine() { Text = new VisualBasicValue<string>("\"Test Class Properties: \" & varName.MyString & \"-\" & varName.MyBool") },
new WriteLine() { Text = new VisualBasicValue<string>("\"Test Class ToString(): \" + varName") }
}
};
var vbSettings = new VisualBasicSettings();
vbSettings.ImportReferences.Add(new VisualBasicImportReference()
{
Assembly = typeof(Test).Assembly.GetName().Name,
Import = typeof(Test).Namespace
});
VisualBasic.SetSettings(wf, vbSettings);
WorkflowInvoker.Invoke(wf);
Console.ReadKey();
}
我必须对Test类进行一些小改动,为字符串连接添加一个+运算符。 公共课测试 { public string MyString {get;组; } public bool MyBool {get;组; }
public override string ToString()
{
return "Test Class : " + this.MyString + " - " + MyBool;
}
public static string operator +(string s, Test t)
{
return s + t.ToString();
}
}