0

この例には 3 つの単純なクラスがあります。

 public class User
{
    public string FirstName { get; set; }
}

public class E : User
{
    public string MiddleInitial { get; set; }
}
public class F : User
{
    public string LastName { get; set; }
}

特定の型を取るためにオーバーロードしている単純な Print メソッドがいくつかあります。応答の書き込みを気にしないでください。これは、ベースにないそのタイプのプロパティを使用するという目標を表示するためだけです。

public void Print(E e)
{
    Response.Write(e.FirstName);
}

public void Print(F f)
{
    Response.Write(f.LastName);
}

型をキャストせずにこれらの命令を機能させる方法に興味がありますか? 合計で、私は4つの別々Userのを持っています。それぞれが同じプロセスを経ます。コードを 4 回ではなく 1 回で取得したいです。LastName以下のこのコードは、Userオブジェクトにないためコンパイルされません。

User u = UserFactory.Get("f");
Print(u);
4

4 に答える 4

3

印刷ロジックをエンティティ自体から分離しておくとよいでしょう (関心の分離)。私はインターフェースを作成しIPrintableます:

public interface IPrintable
{
    string Data { get; }
}

...そしてそれをUserクラスに実装します(abstract可能であれば作成します)

public abstract class User : IPrintable
{
    public string FirstName { get; set; }
    public abstract string Data { get; }
}

Dataその後、各サブクラスはゲッターを実装できます

public class E : User
{
    public string MiddleInitial { get; set; }
    public override string Data { get { return MiddleInitial; } }
}

public class F : User
{
    public string LastName { get; set; }
    public override string Data { get { return LastName; } }
}

...そして、印刷に使用するものは何でもIPrintableオブジェクトを受け入れることができます

public void Print(IPrintable entity)
{
    Response.Write(entity.Data);
}

これには多くの利点があります。まず、他の種類のオブジェクト (オブジェクト以外User) を印刷したい場合は、そのオブジェクトに implement を持たせることができますIPrintablePrintメソッドを変更する必要はありません。

もう 1 つの利点は、Printメソッドが簡単に単体テストできるようになったことです。IPrintableテスト時にモック オブジェクトを渡すだけです。単体テストは具体的な実装に依存していません。

于 2013-11-15T04:01:41.137 に答える
2

代わりにこのように実装する必要があると思います。

void Main()
{
User u = UserFactory.Get("f");
u.Print();
}


public class User
{
public string FirstName { get; set; }

public virtual void Print()
{
    Response.Write(this.FirstName);
}
}

public class E : User
{
public string MiddleInitial { get; set; }

public override void Print()
{
    Response.Write(this.FirstName);
}
}
public class F : User
{
public string LastName { get; set; }

public override void Print()
{
    Response.Write(this.LastName);
}
}
于 2013-11-15T03:51:45.073 に答える
0

UserFactory が正しい型を返すようにします。

F f = UserFactory.GetF();

また:

F f;
UserFactory.Get<F>(out f);
于 2013-11-15T03:48:46.600 に答える
0

あなたはこのようなものを探しています:

public class User
    {
        public string FirstName { get; set; }

        virtual public void Print()
        {
            Console.WriteLine(FirstName);
        }
    }

    public class E : User
    {
        public string MiddleInitial { get; set; }

        override public void Print()
        {
            Console.WriteLine(MiddleInitial);
        }
    }
    public class F : User
    {
        public string LastName { get; set; }

        override public void Print()
        {
            Console.WriteLine(LastName);
        }
    }

    internal class Program
    {
        public static void Main(string[] args)
        {
            var userArray = new User[3];

            userArray[0] = new User { FirstName = "John" };
            userArray[1] = new F { LastName = "Doe" };
            userArray[2] = new E { MiddleInitial = "K" };

            PrintUsers(userArray);
        }

        private static void PrintUsers(User[] userArray)
        {
            foreach (var user in userArray)
            {
                user.Print();
            }
        }
    }

これは、メソッドのオーバーライドを使用して、各呼び出しで適切なメソッドが自動的に選択されるようにします。

于 2013-11-15T03:57:04.860 に答える