将C#lambda表达式转换为VB
本文关键字:VB 转换 表达式 C#lambda | 更新日期: 2023-09-27 18:28:51
在C#中查看模糊日期时间选择器控件?Piotr Czaapla对这个问题的回答正是我所需要的。
不幸的是,我是一个VB.NET的家伙,我对lambda表达式不太熟悉,所以我试图转换代码的结果是放错了几个小时的括号,用砖头砸了我的头。
有没有机会让一些双语向导帮我把C#代码转换成VB.net?
这是有问题的代码:
class FuzzyDateTime
{
static List<string> dayList = new List<string>() { "sun", "mon", "tue", "wed", "thu", "fri", "sat" };
static List<IDateTimePattern> parsers = new List<IDateTimePattern>()
{
new RegexDateTimePattern (
@"next +([2-9]'d*) +months",
delegate (Match m) {
var val = int.Parse(m.Groups[1].Value);
return DateTime.Now.AddMonths(val);
}
),
new RegexDateTimePattern (
@"next +month",
delegate (Match m) {
return DateTime.Now.AddMonths(1);
}
),
new RegexDateTimePattern (
@"next +([2-9]'d*) +days",
delegate (Match m) {
var val = int.Parse(m.Groups[1].Value);
return DateTime.Now.AddDays(val);
}
),
new RegexDateTimePattern (
@"([2-9]'d*) +months +ago",
delegate (Match m) {
var val = int.Parse(m.Groups[1].Value);
return DateTime.Now.AddMonths(-val);
}
),
new RegexDateTimePattern (
@"([2-9]'d*) days +ago",
delegate (Match m) {
var val = int.Parse(m.Groups[1].Value);
return DateTime.Now.AddDays(-val);
}
),
new RegexDateTimePattern (
@"([2-9]'d*) *h(ours)? +ago",
delegate (Match m) {
var val = int.Parse(m.Groups[1].Value);
return DateTime.Now.AddMonths(-val);
}
),
new RegexDateTimePattern (
@"tomorrow",
delegate (Match m) {
return DateTime.Now.AddDays(1);
}
),
new RegexDateTimePattern (
@"today",
delegate (Match m) {
return DateTime.Now;
}
),
new RegexDateTimePattern (
@"yesterday",
delegate (Match m) {
return DateTime.Now.AddDays(-1);
}
),
new RegexDateTimePattern (
@"(last|next) *(year|month)",
delegate (Match m) {
int direction = (m.Groups[1].Value == "last")? -1 :1;
switch(m.Groups[2].Value)
{
case "year":
return new DateTime(DateTime.Now.Year+direction, 1,1);
case "month":
return new DateTime(DateTime.Now.Year, DateTime.Now.Month+direction, 1);
}
return DateTime.MinValue;
}
),
new RegexDateTimePattern (
String.Format(@"(last|next) *({0}).*", String.Join("|", dayList.ToArray())), //handle weekdays
delegate (Match m) {
var val = m.Groups[2].Value;
var direction = (m.Groups[1].Value == "last")? -1 :1;
var dayOfWeek = dayList.IndexOf(val.Substring(0,3));
if (dayOfWeek >= 0) {
var diff = direction*(dayOfWeek - (int)DateTime.Today.DayOfWeek);
if (diff <= 0 ) {
diff = 7 + diff;
}
return DateTime.Today.AddDays(direction * diff);
}
return DateTime.MinValue;
}
),
new RegexDateTimePattern (
@"(last|next) *(.+)", // to parse months using DateTime.TryParse
delegate (Match m) {
DateTime dt;
int direction = (m.Groups[1].Value == "last")? -1 :1;
var s = String.Format("{0} {1}",m.Groups[2].Value, DateTime.Now.Year + direction);
if (DateTime.TryParse(s, out dt)) {
return dt;
} else {
return DateTime.MinValue;
}
}
),
new RegexDateTimePattern (
@".*", //as final resort parse using DateTime.TryParse
delegate (Match m) {
DateTime dt;
var s = m.Groups[0].Value;
if (DateTime.TryParse(s, out dt)) {
return dt;
} else {
return DateTime.MinValue;
}
}
),
};
public static DateTime Parse(string text)
{
text = text.Trim().ToLower();
var dt = DateTime.Now;
foreach (var parser in parsers)
{
dt = parser.Parse(text);
if (dt != DateTime.MinValue)
break;
}
return dt;
}
}
interface IDateTimePattern
{
DateTime Parse(string text);
}
class RegexDateTimePattern : IDateTimePattern
{
public delegate DateTime Interpreter(Match m);
protected Regex regEx;
protected Interpreter inter;
public RegexDateTimePattern(string re, Interpreter inter)
{
this.regEx = new Regex(re);
this.inter = inter;
}
public DateTime Parse(string text)
{
var m = regEx.Match(text);
if (m.Success)
{
return inter(m);
}
return DateTime.MinValue;
}
}
好吧,那里有一堆代码,我不打算全部翻译,但举个例子(假设VS2010或更高版本)。
new RegexDateTimePattern (
@"next +([2-9]'d*) +months",
delegate (Match m) {
var val = int.Parse(m.Groups[1].Value);
return DateTime.Now.AddMonths(val);
}
)
将是
Dim p2 = New RegexDateTimePattern(
"next +([2-9]'d*) +months",
Function(m)
Dim val = Int.Parse(m.Groups(1).Value)
Return DateTime.Now.AddMonths(val)
End Function
)
和
new RegexDateTimePattern (
String.Format(@"(last|next) *({0}).*", String.Join("|", dayList.ToArray())),
delegate (Match m) {
var val = m.Groups[2].Value;
var direction = (m.Groups[1].Value == "last")? -1 :1;
var dayOfWeek = dayList.IndexOf(val.Substring(0,3));
if (dayOfWeek >= 0) {
var diff = direction*(dayOfWeek - (int)DateTime.Today.DayOfWeek);
if (diff <= 0 ) {
diff = 7 + diff;
}
return DateTime.Today.AddDays(direction * diff);
}
return DateTime.MinValue;
}
),
成为
Dim p = New RegexDateTimePattern(
String.Format("(last|next) *({0}).*", String.Join("|", dayList.ToArray())),
Function(m)
Dim val = m.Groups(2).Value
Dim direction = If(m.Groups(1).Value = "last", -1, 1)
Dim dayOfWeek = dayList.IndexOf(val.Substring(0, 3))
If (dayOfWeek >= 0) Then
Dim diff = direction * (dayOfWeek - CType(DateTime.Today.DayOfWeek, Integer))
If (diff <= 0) Then
diff = 7 + diff
End If
Return DateTime.Today.AddDays(direction * diff)
End If
Return DateTime.MinValue
End Function
)
里面还有什么东西在扭你的鼻子吗?
如果它不是VS2010(或者即使它是,并且您不喜欢lambda表达式),那么您所需要做的就是获取每个lambda表达式(VB代码中的"行内"函数),为每个表达式创建显式命名函数(例如,RegexDateTimePattern_Helper2用于最后一个),并传递AddressOf RegexDateTimePattern_Helper2
而不是lambda表达式
即
Function RegexDateTimePattern_Helper2(Match m) as DateTime ''# Dreadful name
dim val = m.Groups[2].Value
dim direction = if(m.Groups(1).Value = "last", -1 ,1)
Dim dayOfWeek = dayList.IndexOf(Val.Substring(0, 3))
If (dayOfWeek >= 0) Then
Dim diff = direction * (dayOfWeek - CType(DateTime.Today.DayOfWeek, Integer))
If (diff <= 0) Then
diff = 7 + diff
End If
Return DateTime.Today.AddDays(direction * diff)
End If
Return DateTime.MinValue
End Function
。.
New RegexDateTimePattern (
String.Format("(last|next) *({0}).*", String.Join("|", dayList.ToArray())),
AddressOf RegexDateTimePattern_Helper2)
我翻译了一个模式和其他的东西。现在您只需要添加其他模式(这应该没什么大不了的。它在Module1中进行了测试。
Module Module1
Sub Main()
Dim res = FuzzyDateTime.Parse("next 2 months")
End Sub
End Module
Public Interface IDateTimePattern
Function Parse(text As String) As DateTime
End Interface
Public Class FuzzyDateTime
Shared dayList As List(Of String) = New List(Of String)() From {"sun", "mon", "tue", "wed", "thu", "fri", "sat"}
Shared parsers As List(Of IDateTimePattern) = New List(Of IDateTimePattern)()
Shared Sub New()
parsers.Add(New RegexDateTimePattern("next +([2-9]'d*) +months", New Func(Of Match, DateTime)(Function(x As Match)
Dim val = Integer.Parse(x.Groups(1).Value)
Return DateTime.Now.AddMonths(val)
End Function)))
End Sub
Public Shared Function Parse(ByVal text As String) As DateTime
text = text.Trim().ToLower()
Dim dt = DateTime.Now
For Each parser In parsers
dt = parser.Parse(text)
If Not dt = DateTime.MinValue Then
Exit For
End If
Next
Return dt
End Function
End Class
Public Class RegexDateTimePattern : Implements IDateTimePattern
Protected inter As Func(Of Match, DateTime)
Protected regEx As Regex
Public Function Parse(text As String) As Date Implements IDateTimePattern.Parse
Dim m = regEx.Match(text)
If m.Success Then Return inter(m)
Return DateTime.MinValue
End Function
Public Sub New(ByVal re As String, ByVal inter As Func(Of Match, DateTime))
Me.regEx = New Regex(re)
Me.inter = inter
End Sub
End Class
附言:我在静态构造函数中添加了模式(尽管可以随意添加),但无法通过内联初始化完成——在我看来,这太难看了。
这里的转换器吐出这个可编译的代码块(在删除了几个"Do"和几个"var"之后):
Imports System.Text.RegularExpressions
Class FuzzyDateTime
Shared dayList As New List(Of String)() From { _
"sun", _
"mon", _
"tue", _
"wed", _
"thu", _
"fri", _
"sat" _
}
Shared parsers As New List(Of IDateTimePattern)() From { _
New RegexDateTimePattern("next +([2-9]'d*) +months", Function(m As Match)
Dim val = Integer.Parse(m.Groups(1).Value)
Return DateTime.Now.AddMonths(val)
End Function), _
New RegexDateTimePattern("next +month", Function(m As Match) DateTime.Now.AddMonths(1)), _
New RegexDateTimePattern("next +([2-9]'d*) +days", Function(m As Match)
Dim val = Integer.Parse(m.Groups(1).Value)
Return DateTime.Now.AddDays(val)
End Function), _
New RegexDateTimePattern("([2-9]'d*) +months +ago", Function(m As Match)
Dim val = Integer.Parse(m.Groups(1).Value)
Return DateTime.Now.AddMonths(-val)
End Function), _
New RegexDateTimePattern("([2-9]'d*) days +ago", Function(m As Match)
Dim val = Integer.Parse(m.Groups(1).Value)
Return DateTime.Now.AddDays(-val)
End Function), _
New RegexDateTimePattern("([2-9]'d*) *h(ours)? +ago", Function(m As Match)
Dim val = Integer.Parse(m.Groups(1).Value)
Return DateTime.Now.AddMonths(-val)
End Function), _
New RegexDateTimePattern("tomorrow", Function(m As Match) DateTime.Now.AddDays(1)), _
New RegexDateTimePattern("today", Function(m As Match) DateTime.Now), _
New RegexDateTimePattern("yesterday", Function(m As Match) DateTime.Now.AddDays(-1)), _
New RegexDateTimePattern("(last|next) *(year|month)", Function(m As Match)
Dim direction As Integer = If((m.Groups(1).Value = "last"), -1, 1)
Select Case m.Groups(2).Value
Case "year"
Return New DateTime(DateTime.Now.Year + direction, 1, 1)
Case "month"
Return New DateTime(DateTime.Now.Year, DateTime.Now.Month + direction, 1)
End Select
Return DateTime.MinValue
''#handle weekdays
End Function), _
New RegexDateTimePattern([String].Format("(last|next) *({0}).*", [String].Join("|", dayList.ToArray())), Function(m As Match)
Dim val = m.Groups(2).Value
Dim direction = If((m.Groups(1).Value = "last"), -1, 1)
Dim dayOfWeek = dayList.IndexOf(val.Substring(0, 3))
If dayOfWeek >= 0 Then
Dim diff = direction * (dayOfWeek - CInt(DateTime.Today.DayOfWeek))
If diff <= 0 Then
diff = 7 + diff
End If
Return DateTime.Today.AddDays(direction * diff)
End If
Return DateTime.MinValue
''# to parse months using DateTime.TryParse
End Function), _
New RegexDateTimePattern("(last|next) *(.+)", Function(m As Match)
Dim dt As DateTime
Dim direction As Integer = If((m.Groups(1).Value = "last"), -1, 1)
Dim s = [String].Format("{0} {1}", m.Groups(2).Value, DateTime.Now.Year + direction)
If DateTime.TryParse(s, dt) Then
Return dt
Else
Return DateTime.MinValue
End If
''#as final resort parse using DateTime.TryParse
End Function), _
New RegexDateTimePattern(".*", Function(m As Match)
Dim dt As DateTime
Dim s = m.Groups(0).Value
If DateTime.TryParse(s, dt) Then
Return dt
Else
Return DateTime.MinValue
End If
End Function) _
}
Public Shared Function Parse(text As String) As DateTime
text = text.Trim().ToLower()
Dim dt = DateTime.Now
For Each parser In parsers
dt = parser.Parse(text)
If dt <> DateTime.MinValue Then
Exit For
End If
Next
Return dt
End Function
End Class
Interface IDateTimePattern
Function Parse(text As String) As DateTime
End Interface
Class RegexDateTimePattern
Implements IDateTimePattern
Public Delegate Function Interpreter(m As Match) As DateTime
Protected regEx As Regex
Protected inter As Interpreter
Public Sub New(re As String, inter As Interpreter)
Me.regEx = New Regex(re)
Me.inter = inter
End Sub
Public Function Parse(text As String) As DateTime Implements IDateTimePattern.Parse
Dim m = regEx.Match(text)
If m.Success Then
Return inter(m)
End If
Return DateTime.MinValue
End Function
End Class