2016-05-05 23 views
0

在一个linq查询中,我需要以某种方式将对linq查询期间创建的对象的引用传递给在同一查询中创建的另一个类... I知道这个问题并不清楚,所以看下面的例子。在Linq表达式中相当于VB.Net“me”

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() 

所以,在上面的代码,其中,“< < < ME >>>”位于,我需要传递到新的Class2对象被创建到Class对象的引用。

我知道我可以使用的一种替代方法是在此查询期间创建class1对象,并跳过对class2对象的引用。然后,在后面的所有class1对象上使用foreach循环,并使用新的linq查询来填充缺少的class2对象......它可以工作,但这并不理想。我想立即填充所有内容,而不是一次完成所有内容。

- EDIT-- 理想情况下,我不必更改现有的类,因为它可能在代码的其他部分有不需要的副作用......如果必须进行更改,我会打开做一些我正在创建一个新的构造函数或属性的东西,正如一些答案中的建议。

有什么想法?

+0

我不太了解VB,但我认为你正在使用属性初始值设定项,所以你可以使用一段代码创建实例,然后使用创建的实例设置属性,然后返回实例。 –

+1

由于您的代码是现在,您正在Linq查询中访问的'class1'中缺少属性声明。 –

回答

0

我做了类似的事情。在Class

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() 

我没有测试这个

+0

这感觉有点骇人听起来,就像我以前在javascript时代做过的事情一样,但它有效,我不必重新编写一堆代码。谢谢。 –

0

那么因为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() 
+1

我认为OP想要注入正在创建的'class1'的同一个实例。不是其他一些例子。 –

+0

Yacoub是正确的。我需要对父类1实例的引用。 –

0

你可以使用构造函数:

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() 
+0

Class1不具有/需要对class2的引用。 Class1是class2的父级,我遇到此问题的原因是因为class2构造函数需要对class1父级的引用。为什么他们没有建立起来......我不知道,但现在我坚持这个设置。 –

+0

@LucasBailey你是什么意思“是父母”?像'class2'继承'class1'吗?您的代码将'class1'的'Property2'设置为'class2'引用。我只是遵循你到目前为止显示的代码。如果你显示'class1'和'class2'的定义,这将有所帮助。 –

+0

不,不会继承......因为...如果我声明了一个独立的class1和class2实例...我将Dim class1作为新的class1()将Dim class2作为新的class1.class2()...可能应该已经把它放在代码中了......我将编辑原始问题 –

0

好吧,我不是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

0

据我所知实例化对象的时候,你不能引用一个对象的实例因为该对象还不存在。如您在class1访问未定义的属性在问题

Public Class foo 
    Public Sub New(bar As foo) 
    End Sub 
End Class 

Dim bar As New foo(bar) ' Null Reference Exception 

你的源代码是不是一个完整的例子,你不能引用class2没有class1下限定它: 即你不能做到这一点。因此,我已经采取了一些自由来将缺失的声明添加到您的代码中。我已经在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()