Linq 和 C# 上的复杂语法

Complicated syntax over Linq and C#

我不知道如何理解以下语法:

public string[] AuthorReferenceID
{
    get { return this.AuthorReference.Select(auth => auth.@ref).ToArray(); }
}

这是 Xsd2 代码生成器根据 XML 模式生成的文件 Bookstore.cs 的一部分。以上代码已添加到生成的文件中。已创建整个应用程序以显示 XML 文件的内容。

XSD 文档(没有前 3 行)如下所示:

<xs:complexType name="Person">
        <xs:sequence>
          <xs:element name="Name" type="xs:string" />
          <xs:element name="Surname" type="xs:string" />
        </xs:sequence>
        <xs:attribute name="id" type="xs:string" />
      </xs:complexType><xs:complexType name="PersonReference">
        <xs:attribute name="ref" type="xs:string" />
      </xs:complexType>

      <xs:complexType name="Publication">
        <xs:sequence>
          <xs:element name="AuthorReference" minOccurs="1" maxOccurs="unbounded" type="b:PersonReference" />
        </xs:sequence>
        <xs:attribute name="title" type="xs:string" use="required" />
      </xs:complexType>

      <xs:complexType name="Book">
        <xs:complexContent>
          <xs:extension base="b:Publication">
            <xs:attribute name="price" type="b:positiveDecimal" use="required" />
            <xs:attribute name="category" type="b:itemCategory" use="required" />
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>

      <xs:simpleType name="positiveDecimal">
        <xs:restriction base="xs:decimal">
          <xs:minExclusive value="0" />
          <xs:fractionDigits value="2" />
        </xs:restriction>
      </xs:simpleType>

      <xs:simpleType name="itemCategory">
        <xs:restriction base="xs:string">
          <xs:enumeration value="ITC" />
          <xs:enumeration value="Mathemath" />
        </xs:restriction>
      </xs:simpleType>

      <xs:element name="Bookstore">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="Books">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Book" minOccurs="0" maxOccurs="unbounded" type="b:Book" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
            <xs:element name="Journals">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Journal" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                      <xs:sequence>
                        <xs:element maxOccurs="unbounded" name="Article" type="b:Publication" />
                        <xs:element name="EditorReference" minOccurs="1" maxOccurs="unbounded" type="b:PersonReference" />
                      </xs:sequence>
                      <xs:attribute name="price" type="b:positiveDecimal" use="required" />
                      <xs:attribute name="category" type="b:itemCategory" use="required" />
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
            <xs:element name="People">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Person" type="b:Person" minOccurs="0" maxOccurs="unbounded" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
        <xs:key name="PERSON_ID">
          <xs:selector xpath="b:People/b:Person" />
          <xs:field xpath="@id" />
        </xs:key>
        <xs:keyref name="ATHBK_PERSON_ID" refer="b:PERSON_ID">
          <xs:selector xpath="b:Books/b:Book/b:AuthorReference" />
          <xs:field xpath="@ref" />
        </xs:keyref>
        <xs:keyref name="ATHART_PERSON_ID" refer="b:PERSON_ID">
          <xs:selector xpath="b:Journals/b:Journal/b:Article/b:AuthorReference" />
          <xs:field xpath="@ref" />
        </xs:keyref>
        <xs:keyref name="EDITJRL_PERSON_ID" refer="b:PERSON_ID">
          <xs:selector xpath="b:Journals/b:Journal/b:EditorReference" />
          <xs:field xpath="@ref" />
        </xs:keyref>
      </xs:element>
    </xs:schema>

所以这并不能完全解释发生了什么,而是分解 Linq:

this

"this" 是一个关键字,意思是 "this object"(或者,换句话说,“这个 class 的这个实例”)。它不是严格需要的,因为对象假定它们正在使用它们的拥有 methods/properties 除非另有说明。

AuthorReference

在 "this" class 中有一个 属性 或称为 "AuthorReference." 的字段 如何使用 我可以假设它是某种集合,可能是列表或数组.但是,在没有看到它的实现的情况下,我无法提供具体细节。

Select(..)

"Select" 是一种 Linq 方法,它根据某种逻辑从集合(在本例中为 "AuthorReference")中选取属性或对象。

auth => auth.@ref

大多数 Linq 查询都遵循 variableName => logic 的格式。所以你可以这样做,例如,Students.Where(aStudent => aStudent.Age > 10),并得到所有超过 10 岁的学生。"aStudent" 或 "auth" 都是你想要的。

代码接着似乎引用了一个名为“@ref”的 属性,它具有一定的价值。所以 Select() 方法是从所有 AuthorReference 项目中选择 @ref 的值。

.ToArray();

...简单的把它从默认值IEnumerable<T>变成数组

最后,Linq 通过 AuthorReference field/property,并为您提供一组 @ref 值。

我还遇到了另一个问题,当我尝试实现 get()

 public Person[] Author
    {
        get
        { return this.Author.Select(a => a.Name).ToArray(); }

我有通讯器: “无法将类型 'string[]' 隐式转换为 'Bookstore.Person[]'。

代码的重要部分如下:

public partial class Publication: IPublication
{
    public Person[] Author
    {
        get
        { return this.Author.Select(a => a.Name).ToArray(); }



        set
        {
            throw new NotImplementedException();
        }
    }


    public string[] AuthorReferenceID
    {
        get { return this.AuthorReference.Select(auth => auth.@ref).ToArray(); }
    }
}

}

界面如下:

   public interface IPublication
{
    Person[] Author { get; set; }
    string title { get; set; }
    string[] AuthorReferenceID { get; }
}

其余代码如下所示:

 [System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2", "1.0.0.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://bookstore.com")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://bookstore.com/", IsNullable=true)]
public partial class Publication {

    private PersonReference[] authorReferenceField;

    private string titleField;


    [System.Xml.Serialization.XmlElementAttribute("AuthorReference")]
    public PersonReference[] AuthorReference {
        get {
            return this.authorReferenceField;
        }
        set {
            this.authorReferenceField = value;
        }
    }


    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string title {
        get {
            return this.titleField;
        }
        set {
            this.titleField = value;
        }
    }
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2", "1.0.0.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://bookstore.com/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://bookstore.com/", IsNullable=true)]
public partial class PersonReference {

    private string refField;

    /// <uwagi/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string @ref {
        get {
            return this.refField;
        }
        set {
            this.refField = value;
        }
    }
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2", "1.0.0.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://bookstore.com/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://bookstore.com/", IsNullable=true)]
public partial class Person {

    private string nameField;

    private string surnameField;

    private string idField;


    public string Name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }


    public string Surname {
        get {
            return this.surnameField;
        }
        set {
            this.surnameField = value;
        }
    }

    /// <uwagi/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }
}