正确地将 .Take(1)(0) 转换为 C# 以修复 Cannot apply indexing with [] 错误?

Correctly Translate .Take(1)(0) to C# to fix Cannot apply indexing with [] error?

我有一些 VB 代码需要翻译成 C#:

<XmlIgnore> Private myState As Object = Me
''' <summary>
''' Fill out the properties of this class by deserializing the given XML into an object of the same type as this class and then copying it's properties.
''' </summary>
''' <param name="xml">String</param>
''' <remarks>This is a shallow copy so won't read any nested objects.</remarks>
Public Sub Deserialize(xml As String)
    Dim newMe As Object 'We don't know our own type so we have to use an object here
    'Read text
    Dim newSerializer As New XmlSerializer(Me.GetType)
    Using newReader As New StringReader(xml)
        newMe = newSerializer.Deserialize(newReader)
        myState = newMe
    End Using
    For Each propinfo In myState.GetType.GetProperties()
        Dim name = propinfo.Name
        Dim realProp = (From p In Me.GetType.GetProperties
          Where p.Name = name And p.MemberType = Reflection.MemberTypes.Property).Take(1)(0)
        If realProp.CanWrite = True Then realProp.SetValue(Me, propinfo.GetValue(myState, Nothing), Nothing)
    Next
End Sub

用了一个工具,结果是这样的:

[XmlIgnore] private object myState;
/// <summary>
/// Fill out the properties of this class by deserializing the given XML into an object of the same type as this class and then copying it's properties.
/// </summary>
/// <param name="xml">String</param>
/// <remarks>This is a shallow copy so won't read any nested objects.</remarks>
public void Deserialize(string xml)
{
    object newMe = null; //We don't know our own type so we have to use an object here
    //Read text
    XmlSerializer newSerializer = new XmlSerializer(this.GetType());
    using (StringReader newReader = new StringReader(xml))
    {
        newMe = newSerializer.Deserialize(newReader);
        myState = newMe;
    }
    foreach (var propinfo in myState.GetType().GetProperties())
    {
        var name = propinfo.Name;
        var realProp = (
            from p in this.GetType().GetProperties()
            where p.Name == name && p.MemberType == System.Reflection.MemberTypes.Property
            select p).Take(1)[0];
        if (realProp.CanWrite == true)
        {
            realProp.SetValue(this, propinfo.GetValue(myState, null), null);
        }
    }
}

但是编译器抱怨 .Take(1)[0] 行出现以下错误:Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.IEnumerable<System.Reflection.PropertyInfo>'

我认为使用 .Take(1).ElementAt(0) 可能是正确的,但我如何才能明确地更改 .Take 以根据 VB 的意图正确获取第一项的第一个元素代码?

后记

请注意,使用 .First 会导致 Cannot assign method group to an implicitly-typed local variable error。相反,必须使用 .ElementAtOrDefault 来获得正确的结果。 See Jon Skeet's answer here for the reason why.

你可以直接使用First方法:

 var realProp = (from p in this.GetType().GetProperties()
        where p.Name == name && p.MemberType == System.Reflection.MemberTypes.Property
        select p).First();

或者使用 FirstOrDefault 并检查 null 如果有机会查询 return 没有任何结果。

您在 C# 中的等效代码为:-

var realProp = (from p in this.GetType().GetProperties()
        where p.Name == name && p.MemberType == System.Reflection.MemberTypes.Property
        select p).Take(1).ElementAtOrDefault(0);

这里,在ElementAtOrDefault中需要传入要获取的元素的索引。

如果您只想获取第一个元素,那么您可以使用 FirstOrDefault :-

var realProp = (from p in this.GetType().GetProperties()
           where p.Name == name && p.MemberType == System.Reflection.MemberTypes.Property
            select p).FirstOrDefault();