VisualBasicValue:访问自定义类及其方法属性
本文关键字:方法 属性 自定义 访问 VisualBasicValue | 更新日期: 2023-09-27 17:53:04
假设我有一个自定义类(任何类),以及它的方法和属性:
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".
操作符'&'没有为'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 ' ?这似乎是我可以在以后的阶段使用,但我要找到任何类型的例子。
我做了一些改变使你的代码工作。
- 变量构造函数是改为使用activityfunction过载
- 第二个WriteLine需要方法显式调用ToString()表达
更正后的代码如下
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使用&用于concat和特定IL指令的操作符op_Concat.
如果你在VB中声明你的类型,你可以重载&操作符,以消除在表达式中调用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控制台应用程序来测试除了工作流之外的东西
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)
下面的代码可以工作。请注意,我用lambda而不是固定值初始化变量的方式,第二个VB表达式使用+而不是&。最后一个对我来说像是一个bug,我将继续跟进。
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类做一个小改动,为字符串连接添加一个+操作符。公开班级测验{公共字符串MyString {get;设置;}公共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();
}
}