【问题标题】:Implementation non-generic IEnumerable from mother class从母类实现非泛型 IEnumerable
【发布时间】:2021-02-24 15:02:00
【问题描述】:

我想就我面临的一个问题向专家请教。在自下而上的方法中,我有一个 StandardAccount 类,它使用几个简单的属性进行初始化,其中一个是枚举(以及一个在实例化时自动设置的 GUID,例如

public class StandardAccount
{
    private Guid _id;
    private string _accName;
    private AccountType _accType;
    private double _balance = 0;
    public enum AccountType
    {
        [Description("Asset")]
        AT,
        [Description("Liability")]
        LY,
        [Description("Profit")]
        PT,
        [Description("Loss")]
        LS
    }

    public StandardAccount(string name, AccountType type)
    {
        this._id = Guid.NewGuid();
        this._accName = name;
        this._accType = type;
        this.Balance = 0;
    }
    public double Balance { get => _balance; set => _balance = value; }
}

一个 Book 类必须有一个或多个 StandardAccounts 列表,而一个 Accounting 类必须有很多 Books。我以可搜索的方式准备 Book 类(将有许多 StandardAccount 列表,我需要稍后在这些列表中通过 GUID 找到 StandardAccount)。我设置我的书类如下:

public class Book
{
    private string _bookName;
    private short _bookNum;
    private Guid _bookId;

    public List<StandardAccount> Accounts { get; set; }
    public IEnumerator<StandardAccount> GetEnumerator() => Accounts.GetEnumerator();

    //compile time err: containing type does not implement interface 'IEnumerable'
    IEnumerator IEnumerable.GetEnumerator() => Accounts.GetEnumerator();
    
    //updated
    public void Add(string name, StandardAccount.AccountType type) => Accounts.Add(new StandardAccount(name, type));

    public Book(Guid? id, short BookNumber, string BookName, IEnumerable<StandardAccount> Account)
    {
        this._bookId = id ?? Guid.NewGuid();
        this._bookNum = BookNumber;
        this._bookName = BookName;
        this.Accounts = new List<StandardAccount>();
    }
    public Guid id { get => _bookId; set => _bookId = value; }
}

我有这两个错误让我无法继续前进,我不明白它们(因为我试图在“母亲”书类而不是 StandardAccount 中实现枚举器) 有人可以帮忙和建议吗?

注意:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

我正在尝试这样做:

//this works fine
StandardAccount stdAccount = new StandardAccount("account one", StandardAccount.AccountType.AT);
//this workds fine
stdAccount.Balance = 123;

//but.. cannot add the account to my book
//ERROR - System.NullReferenceException: 'Object reference not set to an instance of an object.'
myAccounting.Book.Accounts.Add(stdAccount);

【问题讨论】:

  • 为什么需要这个功能?如果您需要迭代帐户,请执行以下操作:foreach (var account in book.Accounts)
  • 一本书不是作者的集合。它作者。拥有一个返回不相关实体的GetEnumerator 会让每个人都感到困惑,即使是作者(你)也会在一段时间后感到困惑
  • 你为什么首先尝试实现IEnumerable?您的List 已经具备这些功能。
  • 对于另一个错误,您需要添加一个Account 的新实例,而不仅仅是两个属性。但同样,不需要该方法,因为 List 属性已经拥有它。
  • @Nick 每个人的意思是,将Book 视为Author 对象的容器是非常不寻常且几乎总是错误的。如果您需要在书中添加标签和关键字怎么办?还是章节?为什么迭代一本书会返回作者而不是章节?

标签: c# ienumerable


【解决方案1】:
//compile time err: containing type does not implement interface 'IEnumerable'
IEnumerator IEnumerable.GetEnumerator() => Accounts.GetEnumerator();

这意味着您使用的是explicit interface implementation。但是 book 类没有实现 IEnumerable 接口,所以会报错。

解决方案是实现接口

public class Book : IEnumerable

或者删除显式部分。请注意,这需要更改名称,因为您已经有一个具有相同签名的方法。

public IEnumerator GetNonGenericEnumerator() => Accounts.GetEnumerator();

但是,正如 cmets 中所述。这可能不是解决问题的好方法。 IE。您应该使用组合而不是继承,即“一本书有一个帐户列表”,而不是“一本书是一个帐户列表”。

从这个问题中,您想要搜索什么以及您期望什么结果并不明显。如果您想搜索具有特定 ID 帐户的书籍,您可以使用:

myBooks.Where(b => b.Accounts.Any(a => a.Id == idToSearchFor));

但您需要公开 ID。如果您希望返回实际帐户,则可以使用:

myBooks.SelectMany(b => b.Accounts).Where(a => a.Id == idToSearchFor);

【讨论】:

  • 非常感谢!你是对的,我澄清一下:我试着做StandardAccount stdAccount = new StandardAccount("account1", StandardAccount.AccountType.AT); 然后简单地做Book.Accounts.Add(stdAccount); 是的,正如你所写的那样,以及其他人,一本书(不是)很多帐户。我尝试在书中逐个列表搜索具有特定(预先知道)GUID id 的帐户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
相关资源
最近更新 更多