C# 使用LINQ,如何从列表中找到具有给定属性值的对象?

C# 使用LINQ,如何从列表中找到具有给定属性值的对象?,c#,.net,asp.net,vb.net,linq,C#,.net,Asp.net,Vb.net,Linq,我有一门课叫问题。此问题具有属性问题ID和问题答案。在foreach中迭代这个问题列表时,我必须找到.QuestionID=12。如果我找到.QuestionID=12,那么我必须立即为.QuestionAnswer=“SomeText”的.QuestionID=14赋值 我不想在.QuestionId=12'中再次迭代以再次找到.QuestionId=14' 是否有任何方法可以使用LINQ直接转到.QuestionID=14 例如: For Each mQuestion As Question

我有一门课叫
问题
。此
问题
具有属性
问题ID
问题答案
。在foreach中迭代这个问题列表时,我必须找到
.QuestionID=12
。如果我找到
.QuestionID=12
,那么我必须立即为
.QuestionAnswer=“SomeText”
.QuestionID=14
赋值

我不想在
.QuestionId=12'中再次迭代以再次找到
.QuestionId=14'

是否有任何方法可以使用LINQ直接转到
.QuestionID=14

例如:

For Each mQuestion As Question In _mQuestions
    If mQuestion.QuestionId = 12 Then
         'Find mQuestion.QuestionID= 14 and insert Somtext to 
          'mQuestion.QuestionAnswer="SomeText"
    End IF
Next

我想你在找这样的东西。如果我有时间的话,我会把它翻译成VB,但我想你可以跟着

if (_mQuestions.Any(q => q.QuestionID == 12)) 
{
   Question question14 = _mQuestions.FirstOrDefault(q => q.QuestionID == 14);
   if (question14 != null)
       question14.QuestionAnswer = "Some Text";
}

不幸的是,您的数据结构(
List
)要求您在找到
Question-12
后再次搜索以查找
Question-14
。如果您的
问题
列表是按ID排序的,则可以进行一些改进,但一般来说,仅通过了解元素属性的值无法直接访问
列表
数组
中的元素

适用于您的问题的数据结构是
Dictionary
,因为它允许通过某些值对对象进行索引,并且可以高效地直接访问这些对象,而无需遍历整个集合

通过调用扩展方法,可以使用Linq将列表转换为字典:

IDictionary<Question> questions = _mQuestions.ToDictionary(q => q.id);

请注意,
ContainsKey
和索引器(运算符[])都是在固定时间内执行的。

请注意,我对它的理解比其他示例更冗长,但我只使用LINQ。(注意下面的C风格评论!)

使用LINQ:

var listOfQ = new List<Question>();

// populate the list of Question somehow...

var q14 = listOfQ.FirstOrDefault(q => q.QuestionID == 14);
if (listOfQ.Any(q => q.QuestionID == 12) && q14 != null)
{
    q14.QuestionAnswer = "SomeText";
}
var listOfQ=new List();
//以某种方式填充问题列表。。。
var q14=listOfQ.FirstOrDefault(q=>q.QuestionID==14);
if(listOfQ.Any(q=>q.QuestionID==12)和&q14!=null)
{
q14.QuestionAnswer=“SomeText”;
}

请不要通过将完美的代码翻译成VB来鼓励人们:更糟糕的是,我只是盯着一个最近编写的VB.net应用程序,它是用VB6语言编写的@MichaelPaulukonis唯一的解决方案是针对Microsoft应用程序的VBA。另一个p.i.n.t.a。vb子集。很好的解决方案!请注意,在这种情况下,您必须确保ID是唯一的,否则.ToDictionary()将失败。为清楚起见,我认为这个问题要求一种机制,避免在
if
语句中显式编写另一个
foreach
循环,而不是完全消除循环。所有涉及
Any()
FirstOrDefault()
的答案都有效地将第二个
foreach
隐藏在各自的实现中。
Private Shared Sub Main(args As String())
    Dim questions As List(Of Question) = GetQuestions()
    Dim question As Question = ( _
        Where q.ID = 14 AndAlso _
              questions.Exists(Function(p) p.ID = 12)).FirstOrDefault()
    If question IsNot Nothing Then
        question.Answer = "Some Text"
    End If
End Sub



 // Build the collection of questions! We keep this simple.
Private Shared Function GetQuestions() As List(Of Question)
    Dim questions As New List(Of Question)()
    questions.Add(New Question(12, "foo"))
    questions.Add(New Question(14, "bar"))
    Return questions
End Function

// You've already got this class. This one is just my version.
Public Class Question
    Public Sub New(id As Integer, answer As String)
        Me.ID = id
        Me.Answer = answer
    End Sub
    Public Property ID() As Integer
        Get
            Return m_ID
        End Get
        Set
            m_ID = Value
        End Set
    End Property
    Private m_ID As Integer
    Public Property Answer() As String
        Get
            Return m_Answer
        End Get
        Set
            m_Answer = Value
        End Set
    End Property
    Private m_Answer As String
End Class
var listOfQ = new List<Question>();

// populate the list of Question somehow...

var q14 = listOfQ.FirstOrDefault(q => q.QuestionID == 14);
if (listOfQ.Any(q => q.QuestionID == 12) && q14 != null)
{
    q14.QuestionAnswer = "SomeText";
}