1

アドレス帳アプリがあり、最終結果をテキスト ファイルに書き込みたい。コマンドを実行できるように、リストを配列に変換するのに苦労していWriteAllLinesます。

インターフェース:

abstract class PhoneBookCore {
    protected string _group;

    public PhoneBookCore(string group) {
        this._group=group;
    }

    public abstract void Add(PhoneBookCore d);
}

class Contect: PhoneBookCore {
    private string _firstName;
    private string _lastName;
    private string _phoneNumber;
    private string _addres;

    public Contect(string group, string firstName, string lastName, string phoneNumber, string addres)
        : base(group) {
        this._firstName=firstName;
        this._addres=addres;
        this._lastName=lastName;
        this._phoneNumber=phoneNumber;
    }
}

class Group: PhoneBookCore {
    private List<PhoneBookCore> elements=new List<PhoneBookCore>();

    public List<PhoneBookCore> elementsList {
        get;
        set;
    }

    public Group(string name)
        : base(name) {

    }

    public override void Add(PhoneBookCore d) {
        elements.Add(d);
    }
}

これが私が立ち往生した場所です

class DataOptins {
    public string Save(Group g) {
        foreach(var item in g) {
            string[] arr=g.elementsList.ToArray();  // <---- :(

        }
        System.IO.File.WriteAllLines(Path, arr); // <---- :(
    }
}
4

3 に答える 3

3

あなたのコードには多くの点で欠陥がありますが、ここではあなたの特定の質問に焦点を当てます。

まず、 ContectToString()クラスのメソッドをオーバーライドする必要があります。

public override string ToString()
{
    return string.Format("{0}{1}{2}{1}{3}{1}{4}", _firstName, "\t", _lastName, _phoneNumber, _addres);
}

(これは単なる例です。もちろん、独自の形式を使用してください)

そして今、リストを文字列の配列にするようなコードがあります:

public string Save(Group g)
{
    string[] lines = g.elementsList.ConvertAll(p => p.ToString()).ToArray();
    System.IO.File.WriteAllLines(Path, lines );
}

これと現在のコードでは、g.elementsList常にnullになるため、例外が発生します。なんで?あなたはそれを決して割り当てないからです。他のプライベートメンバーを持つことはすべて良いことですが、コンパイラは、呼び出したelementsListときに実際にプライベートメンバーが必要であることを認識できませんelements

コードを次のように変更します。

private List<PhoneBookCore> elements = new List<PhoneBookCore>();
public List<PhoneBookCore> elementsList { get { return new List<PhoneBookCore>(elements); } }

そして、「null例外」はもうありません。呼び出し元のコードがプライベートメンバーを変更できないように、パブリックプロパティにリストのコピーを返すようにしたことに注意してください。

于 2013-02-05T08:23:42.487 に答える
3

しないでくださいforeachToArrayリストを呼び出すだけです。ただし、その前に、グループの要素で実際の文字列プロパティを選択する必要があります。 オブジェクトGroup.elementsListのリストです。PhoneBookCoreそれらを変換することはできませんstring-少なくとも、クラスが現在どのように見えるかではありません。したがって、実際に必要な文字列プロパティを選択します。

public string Save(Group g)
{
    string[] arr = g.elementsList.Select(x => x.StringProperty).ToArray();
    System.IO.File.WriteAllLines(Path,arr);
}

またはそれをオーバーライドToStringPhoneBookCoreて使用します:

public string Save(Group g)
{
    string[] arr = g.elementsList.Select(x => x.ToString()).ToArray();
    System.IO.File.WriteAllLines(Path,arr);
}

を受け入れる のToArrayオーバーロードが存在するため、最後に、実際には呼び出しを完全にドロップできます。WriteAllLinesIEnumerable<string>

public string Save(Group g)
{
    System.IO.File.WriteAllLines(Path, g.elementsList.Select(x => x.ToString()));
}
于 2013-02-05T08:17:50.097 に答える
1

1) method がすべての派生クラスの要件ではない場合は、abstractAddではなくvirtualとして宣言します。

2)クラスToString()のオーバーライド。Contect必要に応じて、 forPhoneBookCoreもオーバーライドします。クラスでは次のContectようになります。

public override String ToString() {
    return
        (new[] { _firstName, _lastName, _phoneNumber, _addres }).Aggregate((a, b) => a+"\t"+b);
}

それらを集約するルールは、要件によって異なります。

3)セマンティクスを意味のあるGroupクラスに実装するIEnumerable<String>ため、公開する必要はありませんelementsList。これを実装する必要がありますが、次GetEnumerator()のことは簡単です。

partial class Group: PhoneBookCore, IEnumerable<String> {
    IEnumerator IEnumerable.GetEnumerator() {
        return this.GetEnumerator();
    }

    public IEnumerator<String> GetEnumerator() {
        return elements.Select(x => x.ToString()).GetEnumerator();
    }
}

これら 3 つのことをすべて実行したら、次のSaveようにメソッドを簡単に実装できます。

public string Save(Group g) {
    string[] arr=g.ToArray(); // <---- :(
    System.IO.File.WriteAllLines(Path, arr); // <---- :(

    // notice: you did not show what to return in original code
}

DataOptins4) クラス名をDataOptions、およびContectに修正することを提案しますContact

Saveさて、以下はコードの完成です(返されるものを除く):

abstract class PhoneBookCore {
    protected string _group;

    public PhoneBookCore(string group) {
        this._group=group;
    }

    public virtual void Add(PhoneBookCore d) {
    }
}

class Contect: PhoneBookCore {
    private string _firstName;
    private string _lastName;
    private string _phoneNumber;
    private string _addres;

    public override String ToString() {
        return
            (new[] { _firstName, _lastName, _phoneNumber, _addres }).Aggregate((a, b) => a+"\t"+b);
    }

    public Contect(string group, string firstName, string lastName, string phoneNumber, string addres)
        : base(group) {
        this._firstName=firstName;
        this._addres=addres;
        this._lastName=lastName;
        this._phoneNumber=phoneNumber;
    }
}

class Group: PhoneBookCore, IEnumerable<String> {
    IEnumerator IEnumerable.GetEnumerator() {
        return this.GetEnumerator();
    }

    public IEnumerator<String> GetEnumerator() {
        return elements.Select(x => x.ToString()).GetEnumerator();
    }

    private List<PhoneBookCore> elements=new List<PhoneBookCore>();

    public List<PhoneBookCore> elementsList {
        get;
        set;
    }

    public Group(string name)
        : base(name) {
    }

    public override void Add(PhoneBookCore d) {
        elements.Add(d);
    }
}

class DataOptins {
    public string Save(Group g) {
        string[] arr=g.ToArray(); // <---- :(
        System.IO.File.WriteAllLines(Path, arr); // <---- :(

        // notice: you did not show what to return in original code
    }
}
于 2013-02-05T09:30:25.350 に答える