4

多層アプリケーションを構築しています。

プレゼンテーション レイヤーからビジネス レイヤーにオブジェクトを渡すとき、ビジネス レイヤーはプレゼンテーション レイヤーの具象クラスを認識していないため、オブジェクトをインターフェイス タイプにキャストしたいと考えています。

    public ActionResult SubmitSurvey(SurveyAnswer answers)
    {

        ISurveyAnswer answer = (ISurveyAnswer)answers;

        bc.SaveSurvey(answer);

        return null;
    }

このクラスSurveyAnswerは、インターフェイス ISurveyAnswer を実装します。

ビジネスレイヤーでタイプを確認すると:

 public void SaveSurvey(ISurveyAnswer answer)
        {
            String type = answer.GetType().Name;
        }

GetType().Name メソッドは、プレゼンテーション層からの具象クラスである SurveyAnswer を返します。それをすることになっていますか?

4

2 に答える 2

10

キャストによってオブジェクトのタイプが変更されることはありません。オブジェクトは常に作成時と同じままです。キャストは、オブジェクトにアクセスするためのインターフェイスを変更するだけです。必要に応じて、オブジェクトの「ビュー」を変更します。しかし、それは問題ではありません。あなたがしていることは正しいです。UIレイヤーが気にするのはISurveyAnswerインターフェイスだけです。オブジェクトの具象型がそのインターフェイスを実装している限り、すべてが正常に機能し、期待どおりに機能します。そうすることの美しさは、UIレイヤーに任意の種類のオブジェクト(モックオブジェクトを含む)を与えることができ、オブジェクトが同じインターフェイスを実装している限り、UIは機能し、気にしないということです。GetTypeを使用すると、オブジェクトを検査して、オブジェクトの実際のタイプを確認できますが、ほとんどの場合、そうすべきではありません。UIレイヤーには関係ありません。提供されたオブジェクトがそのインターフェイスを実装し、適切に機能する限り、UIも同様に機能します。

クラスまたはメソッドが何らかのタイプのオブジェクトを渡すように要求する場合、理想的には、可能な限り最も狭い実装または基本タイプを常に要求する必要があります。したがって、たとえば、アイテムのリストを取得するメソッドがある場合、次のようになります。

void printList(List<Dog> dogs)
{
    foreach(Dog dog in dogs)
        printDog(dog);
}

ただし、技術的には、メソッドは実際にはオブジェクトを必要としませんList<>。これは、リスト内のアイテムを列挙するだけであるためです。List<>タイプ自体のメンバーは使用せず、タイプIEnumerable<>によって実装されるインターフェイスのメンバーを使用するだけList<>です。したがって、この場合は、次のようにメソッドをコーディングすることをお勧めします。

void printList(IEnumerable<Dog> dogs)
{
    foreach(Dog dog in dogs)
        printDog(dog);
}

ここで、メソッド内でリストを列挙する必要があるだけでなく、リスト内のアイテムの総数も必要な場合IEnumerableは、十分ではありません。しかし、それでも、完全なList<>型は必要ありません。次のように、ICollection<>型(これもによって実装されList<>ます)が必要です。

void printList(ICollection<Dog> dogs)
{
    printTotal(dogs.Count);
    foreach(Dog dog in dogs)
        printDog(dog);
}

ただし、メソッドが各アイテムのインデックスを取得する必要がある場合は、それだけでICollection<>は不十分です。メソッドにはIList<>型が必要です。たとえば、この例は、犬のリストを印刷し、リスト内の他のすべての犬を強調表示する方法を示しています。

void printList(IList<Dog> dogs)
{
    printTotal(dogs.Count);
    for(Dog dog in dogs)
        if (dogs.IndexOf(dog) % 2 == 0)
            printDog(dog);
        else
            printHighlightedDog(dog);
}

dogsこれらの例のいずれにおいても、引数を別の型にキャストする必要がなかったことに気付くでしょう。必要なものに合わせて引数を適切に入力したので、その型のインターフェイスを介して使用します。これらのすべての例では、List<Dog>オブジェクトprintListをキャストせずにメソッドに渡すことができます(List <>はこれらのインターフェイスをすべて実装しているため、暗黙的にキャストできます)。

List<Dog> dogs = new List<Dog>();
dogs.Add(new Dog());
printList(dogs);

これは、ポイントを説明するための非常に単純な例であることに注意してください。実際のシナリオでは、さまざまな理由で、提供するすべてのものを技術的に必要としない場合でも、List<>要求することがよくあります。現在の機能しか必要としない場合でも、IList<>このメソッドには将来的に機能が必要になる可能性が非常に高いことをご存知かもしれません。ただし、この原則は、メソッドの引数の型を決定するときに覚えておくと非常に良いものです。IList<>IEnumerable<>

メソッドに渡されるオブジェクトの実際のタイプを知る必要はほとんどありません。本当に知っておく必要があるのは、特定のインターフェイスを実装しているため、その特定のインターフェイスを介してその機能にアクセスできることだけです。

于 2012-05-31T12:50:03.513 に答える
5

インターフェイスタイプにキャストしたい

する必要がない。具象型が型を実装している場合は、キャストする必要はありません。

これは問題なく機能します。

public ActionResult SubmitSurvey(SurveyAnswer answers)
{
    bc.SaveSurvey(answers);
    return null;
}

GetType()。Nameメソッドは、プレゼンテーション層の具象クラスであるSurveyAnswerを返します。それをすることになっていますか?

そのとおりです。渡された実際のタイプ(キャスト先)が返されます。

于 2012-05-31T12:49:40.203 に答える