【问题标题】:VB.Net "me" equivalent in Linq expressionLinq 表达式中的 VB.Net“我”等价物
【发布时间】:2016-05-05 15:22:21
【问题描述】:

在 linq 查询中,我需要以某种方式将对在 linq 查询期间创建的对象的引用传递给在同一查询中创建的另一个类...我知道这个问题不清楚,所以请参阅下面的例子。

 public class class1
      public class class2
           private _class1 as class1
           public property OtherProperty1 as int

           Public sub new(cls1 as class1)
                _class1 = cls1
           End Sub
      End class
      public property Property1 as int
      public property Property2 as class2
 End Class

 Dim e as List(of class1) = (From row as datarow in dataTable.Rows
                             Select New class1 with {
                                  .Property1 = row.Item("Property1"),
                                  .Property2 = new class2(<<< ME >>>) with {
                                      .OtherProperty1 = row.Item("OtherProperty1")
                                  }
                             }).ToList()

因此,在上面的代码中,“>>”所在的位置,我需要将对正在创建的 class1 对象的引用传递给新的 class2 对象。

我知道我可以使用的另一种方法是在此查询期间创建 class1 对象,跳过对 class2 对象的引用。然后,稍后,在所有 class1 对象上使用 foreach 循环并使用新的 linq 查询来填充缺少的 class2 对象……它会起作用,但并不理想。我想一次填充所有内容,而不是一次完成其中的一部分。

--编辑-- 理想情况下,我不必更改现有类,因为它可能会在代码的其他部分产生不必要的副作用……如果我必须进行更改,我会愿意做一些我正在创建新构造函数的事情或属性,如某些答案中所建议的那样。

有什么想法吗?

【问题讨论】:

  • 我对VB不太了解,但我认为您使用的是属性初始化程序,因此您可以先使用一段代码创建实例,然后使用创建的实例设置属性,然后返回实例。
  • 正如您现在的代码一样,您在 Linq 查询中访问的 class1 中缺少属性声明。

标签: vb.net linq lambda


【解决方案1】:

我做过类似的事情。在class1

Public Class class1
    Public ReadOnly Property this As class1
        Get
            Return Me
        End Get
    End Property

End Class

那你可以直接拨打.this

Dim e as List(of class1) = (From row as datarow in dataTable.Rows
                         Select New class1 with {
                              .Property1 = row.Item("Property1"),
                              .Property2 = new class2(.this) with {
                                  .OtherProperty1 = row.Item("OtherProperty1")
                              }
                         }).ToList()

我没有测试过这个

【讨论】:

  • 感觉有点骇人听闻,就像我以前在 javascript 时代做的事情一样,但它可以工作,而且我不必重新编写一堆代码。谢谢。
【解决方案2】:

既然 Class2 的构造函数需要 Class1 的实例,你就不能创建它吗?

Dim myClass1 As New class1

 Dim e as List(of class1) = (From row as datarow in dataTable.Rows
                             Select New class1 with {
                                  .Property1 = row.Item("Property1"),
                                  .Property2 = new class2(myClass1) with {
                                      .OtherProperty1 = row.Item("OtherProperty1")
                                  }
                             }).ToList()

【讨论】:

  • 我认为 OP 想要注入正在创建的 class1 的相同实例。不是其他实例。
  • Yacoub 是正确的。我需要对父 class1 实例的引用。
【解决方案3】:

你可以使用构造函数:

Class class1
   Public Property Property1 As Object
   Public Property Property2 As class2

   Public Sub New(Property1 As Object, OtherProperty1 As Object)
      Me.Property1 = Property1
      Property2 = new class2(Me, OtherProperty1)
   End Sub
End Class

Class class2
   Private otherClass As class1

   Public Property OtherProperty1 As Object

   Public Sub New(class1 As class1, OtherProperty1 As Object)
      otherClass = class1
      Me.OtherProperty1 = OtherProperty1
   End Sub
End Class

Dim e as List(of class1) = (From row as datarow in dataTable.Rows
                            Select New class1(
                               row.Item("Property1"),
                               row.Item("OtherProperty1")
                           )).ToList()

【讨论】:

  • Class1 没有/不需要对 class2 的引用。 Class1 是 class2 的父级,我遇到此问题的原因是因为 class2 构造函数需要对 class1 父级的引用。为什么他们一开始没有构建它……我不知道,但现在我被这个设置困住了。
  • @LucasBailey “是父母”是什么意思?就像class2 继承自class1?您的代码将 Property2class1 设置为 class2 引用。我只是按照您到目前为止显示的代码进行操作。如果您显示class1class2 的定义会有所帮助。
  • 不,不是继承...如...如果我声明 class1 和 class2 的独立实例...我会将 class1 调暗为新的 class1() 将 class2 调暗为新的 class1.class2 ()...可能应该把它放在代码中...我将编辑原始问题
  • 我刚刚添加了类定义......所以你可以看到,我正在努力解决的愚蠢部分是以前的开发人员决定他想要 class1 中的一些属性,这些属性是所有class1、class2、class3...等(大约 4 个其他类)中的其他属性,其中每当子属性发生变化时......将重新计算类 1 中的计算属性。这就是为什么我的子类需要对父类的引用,以便父类可以在属性更改后执行重新计算代码。
【解决方案4】:

好的,我不是 VB 方面的专家,这可能可以做得更好,但你可以这样做:

Dim e As List(Of Class1) = (From row As DataRow In dataTable.Rows
                            Select Create(row)).ToList()

Function Create(row As DataRow) As Class1
    Dim result As Class1 = New Class1 With
    {.Property1 = row.Item("Property1")}

    result.Property2 = New Class2(result) With
    {.OtherProperty1 = row.Item("OtherProperty1")}
    Return result
End Function

我试图在没有额外功能的情况下做到这一点,但如果在 VB 中可行,我不会这样做。

【讨论】:

    【解决方案5】:

    据我所知,您在实例化对象时无法引用该对象的实例,因为该对象尚不存在。 即你不能这样做:

    Public Class foo
        Public Sub New(bar As foo)
        End Sub
    End Class
    
    Dim bar As New foo(bar) ' Null Reference Exception
    

    您在问题中的源代码不是一个完整的示例,因为您正在访问class1 中的未定义属性,并且您不能在没有在class1 下限定它的情况下引用class2。因此,我冒昧地将缺少的声明添加到您的代码中。我在 class2 上添加了 .toString() 函数只是为了表明 _class1 正在被引用。请注意,我在下面的代码中使用的是 VB 14;并不是这个例子的核心需要它,而是使用$""String.Format() 干净得多

    这是我的代码版本:

    Public Class class1
        Public Property Property1 As Object
        Public Property Property2 As class2
        Public Class class2
            Private _class1 As class1
    
            Public Property OtherProperty1 As Int32
    
            Public Sub New(cls1 As class1)
                _class1 = cls1
            End Sub
    
            Public Property Property1 As Int32
    
            Public Overrides Function toString() As String
                Return $"{_class1.Property1.ToString} success"
            End Function
        End Class
    End Class
    

    这是我的解决方案:

    Dim dt As New DataTable()
    dt.Columns.AddRange({New DataColumn("Property1"), New DataColumn("OtherProperty1")})
    dt.Rows.Add({"foobar", 123I})
    
    Dim CreateNewClass1 = Function(x As DataRow)
                              Dim cls1 As New class1 With {.Property1 = x.Item("Property1")}
                              cls1.Property2 = New class1.class2(cls1) With {
                                .OtherProperty1 = x.Item("OtherProperty1")}
                              Return cls1
                          End Function
    
    Dim e As List(Of class1) = (From row As DataRow In dt.Rows
                                Select CreateNewClass1(row)).ToList()
    
    e.ForEach(Sub(x) Console.WriteLine($"{x.ToString}
    class1.property1 = {x.Property1.ToString} 
    class1.Property2 = {x.Property2.toString} 
    class2.otherProperty1 = {x.Property2.OtherProperty1}"))
    
    Console.ReadLine()
    

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多