0

私はまるでドークのように感じます。私はしばらくの間コーダーをしていて、これまで言語でこれに遭遇したことはありません。私は常にコンストラクターを「追加の」ものでオーバーライドしてきました。そのため、いくつかのクラスを切り捨てています。説明:

public enum Flags : ushort
{
   Item = 1,
   Player = 2
}

public class Item
{
    private Flags _flags;
    private int _owner;
    private String _pwd;

    public Item(Flags flags, int owner, String pwd = null)
    {
        _owner = owner;
        _flags = flags;
        _pwd = pwd;
    }
}

public class Connection
{
    ... stuff irrelevant to question
}

Itemですから、プレイヤーがログインするときに、タイプがあり、接続がある子孫を取得できるようにしたいのですPlayer。現実的には、それは単なるアイテムです。

だから私はスターターとしてこれをしました:

public class Player : Item
{
    public Connection Conn;
}

と言いました:

アイテムには、0個の引数を取るコンストラクターが含まれていません

まあ、私の目には、私はそれを言ったことはありません..プレーヤーは、アイテム、既存のアイテムからコピーされるだけで「作成」されることは決してありません、私はそれに追加します、1つの追加のプロパティ(これは私のコードとして残るものではありません、しかしそれは出発点でした)..したがって、実際の20以上のプロパティを一方から他方に手動でコピーする必要はありません。リアルに使えるようになりたい

Player p = (Player)item_wanted;

次に、接続を割り当てますp Player。直接作成されることはありません。アイテムはアクティブなプレーヤーのみであり、技術的にはプレーヤーが複数の接続を持つ可能性があるため、アイテムに接続を割り当てたくありません。

もちろん、最初の愚かな考えは

Public Payer(Item i)
{
    this = (Player) i;
}

ええ、悲しいことにそれはできませんね。:(しかし、事実上、それはほとんど私が欲しいものです!

あなたが尋ねる前に、私は接続にアイテムを追加することを検討しました...しかし論理的にはあなたはそれをそのように考えることはありません...

それで、どうすればそれを回避できますか?1つのプロパティを追加して、それを別のプロパティと呼びたい...

OK、なぜそれがインストラクターについて言ったのかわかります、それが元のクラスで利用可能なものとうまくいかなかったことに失望しました、しかし大丈夫、私はそれを理解します。ただし、元のアイテムはすでに生きているので、コピーは必要ありません。機能を追加したかったのですが...譲ります。この質問は閉じることができます。**

4

6 に答える 6

3

最初の問題: アイテムにはプライベート プロパティがあるため、子孫は _flags にアクセスできません。それらを保護するように宣言すると、子孫はアクセスできますが、次のようなコンストラクターを使用することはできません。

    public Player(Item i) : base(i._flags,i._owner,i._pwd)

したがって、Item プロパティを public にすると、次のようになります。

public enum Flags : ushort

{
   Item = 1,
   Player = 2
}

public class Item
{
    public Flags _flags;
    public int _owner;
    public String _pwd;


public Item(Flags flags, int owner, String pwd = null)
 {
  _owner=owner;
  _flags=flags;
  _pwd=pwd;
 }
}

public class Connection
{
    public Connection()
    {
    }
}
public class Player : Item
{
    public Connection Conn;
    public Player(Item i) : base(i._flags,i._owner,i._pwd)
    {
        // and add your "additional thing"
        // This calls the base constructor, and then you can add codes...
    }

}

したがって、これを行うことができます:

    Item p = new Item(Flags.Item,12);  // Item is something existing
    Player x = new Player(p);

プレーヤー x とアイテム p は同じではないことに注意してください。プレイヤー x はアイテム p から作成されるため、p を変更します。x には影響しません。コード:

    Item p = new Item(Flags.Item,12);
    Player x = new Player(p);         // instead of: Player p = (Player)item_wanted;
    p._owner = 20;

20 (p._owner) と 12 (x._owner) が表示されます。アイテムに基づいて新しいプレーヤーを作成した後、アイテムを「忘れる」ことができます。

于 2012-09-14T10:55:24.923 に答える
2

その理由は、子クラスのコンストラクターが親クラスの既定のコンストラクターを暗黙的に呼び出すためです。親クラスでは、パラメーターが 0 のコンストラクターを定義していないため、このエラーが発生しています。

Playerクラスのコンストラクターを定義していませんが。次の呼び出しのようなデフォルトのコンストラクターを想定します。

Player() : base()
{
}

この問題を解決するには、基本クラスで空のデフォルト コンストラクターを作成するか、コンストラクターを使用して子クラスでItemキーワードを使用して特定のコンストラクターを呼び出します。base

Public Payer(Item i) :base(arg1,arg2,arg3)
{

}

コンストラクターの使用 - MSDN

派生クラスでは、基本クラスのコンストラクターが base キーワードを使用して明示的に呼び出されない場合、既定のコンストラクターが存在する場合は暗黙的に呼び出されます。

于 2012-09-14T10:03:32.537 に答える
2

から継承する場合はItem、そのコンストラクターを呼び出す必要がありますPlayer

public Player(Flags flags, int owner, String pwd = null) : base(flags, owner, pwd) 
{
   // Do something else
}

または、パラメータなしでコンストラクタを定義する必要がありますItem

于 2012-09-14T10:04:29.810 に答える
1

次のアイテムにコンストラクターを追加します。

public Item() { };
于 2012-09-14T10:05:26.270 に答える
1

Playerからプロパティをコピーしたい場合Item、継承は適していない可能性があります。構成を使用できます:

class Player
{
    Item item;
    public Player(Item item)
    {
        this.item = item; // store reference to item here, it will point to the same object you used for construction, no copying needed later
    }
}

itemなどを呼び出すパブリック プロパティとして公開する必要もありません。クラスplayer.Item.Flagsのラッパー プロパティを作成するだけでかまいません。Player

class Player
{
    Item item;
    public Player(Item item)
    {
        this.item = item; // store reference to item here, it will point to the same object you used for construction, no copying needed later
    }

     public string Name { get { return item.Name; } } // etc...
}
于 2012-09-14T10:05:27.907 に答える
1
public class A
{
   private int _p;
   public A(int param) { _p = param;}
}

public class B : A 
{
    public B(int param) : base(param)
    {
    }

    public int x { get; set; }
}

A ( var item = new A(1);) のインスタンスがある場合、それを B に変換することはできません。しかし、B ( var player = new B(1);) のインスタンスがある場合は、A にキャストできます。

var casted = (A)item;

では、既存のアイテムであるアイテムからコピーされるだけで Player が「作成」されることはないとはどういう意味ですか?

于 2012-09-14T10:14:54.740 に答える