2

いくつかの共通のプロパティを共有しているいくつかの UserControls があります。例:

private List<MyObject> Sample
        {
            get
            {
                return Session["MyObject"] as List<MyObject>;
            }
            set
            {
                Session["MyObject"] = value;
            }
        }

これをプロジェクト内のすべてのユーザー コントロールで共有したいと考えています。(もちろん、ソリューション内の他のプロジェクトではありません)。私がやろうとしているのは、別のクラスを作成し、そのクラスから継承することです。何かのようなもの:

public class SampleBase : Web.UI.UserControl
{
 protected List<MyObject> Sample
            {
                get
                {
                    return Session["MyObject"] as List<MyObject>;
                }
                set
                {
                    Session["MyObject"] = value;
                }
            }
}

そして、私のコントロールは、そのクラスから派生することにより、これらの値を継承できます。

partial class myControl : SampleBase 

私が遭遇する 1 つの問題は、コントロールに既に何かが継承されている場合、ベースから派生できないことです。

partial class myControl : SomethingELSE

それ以外の場合は問題なく動作しますが、それが良いアプローチであるかどうかはわかりません。提案を探しています。

4

4 に答える 4

10

私の理解が正しければ、ユーザーコントロールの継承階層を取り除きたいだけです

別のアプローチは、拡張メソッドを使用することです

例えば:

ユーザー コントロールをマークするためのインターフェイス

public interface IMyUserControlMark { }

拡張機能

public static class MyUserClassExtensions
{
    public static List<object> GetSampleData(this IMyUserControlMark myUserControl)
    {
        if (HttpContext.Current.Session["MyObject"] == null)
        {
            return Enumerable.Empty<object>().ToList();
        }

        return HttpContext.Current.Session["MyObject"] as List<object>;
    }

    public static void SetSampleData(this IMyUserControlMark myUserControl, List<object> myObject)
    {
        HttpContext.Current.Session["MyObject"] = myObject;
    }
}

ユーザーコントロール

public partial class Content1 : System.Web.UI.UserControl, IMyUserControlMark
{
     ...
}

public partial class Content2 : System.Web.UI.UserControl, IMyUserControlMark
{
     ....
}

これで、UserControl 内から、または次のように ASPX コード ビハインドから拡張メソッドを呼び出すことができるようになります。

ユーザーコントロールから

var myObject = this.GetSampleData();
this.SetSampleData(myObject);

ASPXコードビハインドから

var myObject = this.uc1.GetSampleData();
this.uc1.SetSampleData(myObject);
于 2012-07-30T20:51:43.973 に答える
2

これは、「継承よりも構成を優先する」必要がある典型的な例です。

クラスから継承する代わりに、クラスのインスタンスへの参照を保持します。次に、クラスのメソッド/プロパティにアクセスするための単純なパススルー コードを提供します。

したがって、あなたの例では:

public class SomeBehavior
{
    public List<MyObject> Sample
    {
        get { return Session["MyObject"] as List<MyObject>; }
        set { Session["MyObject"] = value; }
    }
}

public class MyControl : UserControl
{
    private SomeBehavior _someBehavior;

    public MyControl()
    {
        _someBehavior = new SomeBehavior();
    }

    public List<MyObject> Sample
    {
        get { return _someBehavior.Sample; }
        set { _someBehavior.Sample = value; }
    }   
}

もう 1 つのオプションは、動作クラスへの直接アクセスを許可することです。

public class MyControl : UserControl
{
    public SomeBehavior SomeBehavior { get; private set; }

    public MyControl()
    {
        SomeBehavior = new SomeBehavior();
    }
}

この利点は、パススルー コードを記述する必要がないことです。不利な点は、「直接の友人とのみ話すべきである」というデメテルの法則に違反していることです。このようにすると、 を使用する他のクラスはMyControlについて知る必要がありSomeBehaviorます。Demeter の法則に従うと、コードの保守性と適応性が向上しますが、多くのパススルー コードが必要になります。

于 2012-07-25T22:04:12.837 に答える
0

以前のソリューションとは別に、MVC / MVPパターンを適用するときが来たのではないでしょうか?Webフォームには、WebFormsMVPと呼ばれる優れたフレームワークがあります。linkライブラリ には、Cross Presenter Messagingと呼ばれるメカニズムがあり、パブリッシュ/サブスクライブパターンを使用してコントロール間でデータを共有できます。より良い説明については、ここここを見てください

私は図書館にチャンスを与えることを提案します:)

于 2012-07-30T21:14:46.463 に答える
0

C# では、1 つのクラスからのみ継承し、複数のインターフェイスを実装できます。

これは許可されています:

partial class myControl : SampleBase

partial class myControl : SampleBase, Interface1

partial class myControl : SampleBase, Interface1, Interface2, Interface3

これは許可されていません:

partial class myControl : SomethingELSE, SampleBase

設計が満足できる場合は、SomethingELSE継承元を作成してみてください。SampleBaseそうでない場合は、SampleBase@DanM も示唆しているため、カプセル化を必要とする各コントロールのプロパティとしてカプセル化することをお勧めします。

于 2012-08-02T01:32:14.347 に答える