0

「親」オブジェクトで、特定の瞬間に「子」で何らかのメソッドを呼び出すことが許容されるかどうかを調べる必要があります。たとえば、親オブジェクト (コンポーネント) には子オブジェクト (またはコンポーネント パーツ) が含まれており、親は現在破棄しているため、すべての (または特定の) 子アクティビティを禁止する必要があります (つまり、新しいサービス スレッドの開始、新しいクライアント リクエストのキューへの登録など)。 .)。

public class Parent
{
    public bool IsMethodCallAcceptable(reference_to_method) {...}
}

public class Child
{
    public int SomeMethod(int intArg, string stringArg)
    {
        if(!_parent.IsMethodCallAcceptable(reference_to_SomeMethod_with_actual_args))
            throw new ...
        ...
    }

    private void AnotherMethod(string param = null) {...}
    {
        if(!_parent.IsMethodCallAcceptable(reference_to_AnotherMethod_with_actual_args))
            throw new ...
        ...
    }

    private Guid ThirdMethod()
    {
        if(!_parent.IsMethodCallAcceptable(reference_to_ThirdMethod))
            throw new ...
        ...            
    }
}

それを行う方法はありますか?

4

6 に答える 6

7

注: タイトルではなく、質問に答えています。他の人がタイトルに答えています。

一部のオブジェクトには isDisposed プロパティがあります。親がそれを実装していて、そのときだけメソッドを呼び出したくない場合は、はい。そうでなければいいえ。親のソースを制御する場合は、必要なことを行うプロパティを追加できます。

ソースを管理しておらず、isDisposed 以外をチェックしたい場合、または親が isDisposed を実装していない場合は、公開されているプロパティをチェックできる可能性がありますが、一般に、メソッドが公開されている場合は、いつでも呼び出すことができること。リフレクションを介してプライベート メソッドを呼び出している場合は、チャンスをつかんでいます。

コメントに応じて編集: 説明を考えると、デリゲートは、親にプロパティとメソッドを追加することによって簡単に実行できない追加機能を提供しません (ソースを制御しない場合、それらは役に立ちません)全て)。説明したシナリオに対処するための最良の方法 (CAR.ENGINE.START がガス欠の場合、Start メソッドが例外をスローするか、エンジンを始動しようとした結果を示す値を返すことです)。

于 2012-07-21T18:17:35.253 に答える
2

デリゲートを使用しますか?

http://msdn.microsoft.com/en-us/library/ms173171%28v=vs.80%29.aspx

于 2012-07-21T18:04:51.863 に答える
0

これらのメソッドが子クラスにネイティブである場合、親はそれらについて何も知ることができません。 ライスの定理は、コードを見ることさえできれば、あらゆる種類の問題を引き起こします。それらが親クラスにネイティブであり、子クラスでオーバーライドされている場合、同じ問題 (ただし程度は低い) は、子クラスが親クラスのすべて (およびそれらのことのみ) を実行することを実際に保証できないためです。クラスはそうします。実際、あなたはそれが何か違うことをすることを保証することができます. (そうでない場合、なぜオーバーライドするのですか?)

それらが親クラスにネイティブであり、子でオーバーライドできない場合は、オブジェクトがそのようなことを行うのに有効な状態にあるかどうかを確認し、そうでない場合は例外をスローします。

実際の有効性チェックに関する限り、あなたの例では、次のようなメソッドを使用できますbool IsDisposing()。それ以外の場合は、別の方法で状態を追跡できます。たとえば、次のようなプライベートメソッドCanDoThisThing()が役立つ場合があります。一般的な操作名 (操作ではありません。その実行不可能性は既に確立されています) を取るメソッドを持つことは、私にはちょっと壊れているように思えます。

于 2012-07-21T18:37:38.533 に答える
0

関数Func<T, TResult> リンクを使用

于 2012-07-21T18:05:47.980 に答える
0

最も簡単な方法は、参照の代わりに URI を渡すことです。

たとえば、「NS.Child.ThirdMethod」。

それ以外の場合、デリゲートは関数参照に最も近いものです。必要に応じてそれを渡すことができます。

ただし、このメソッドは OOP 概念規則に準拠していません。基本クラスは、その子クラスについて何も認識してはなりません。なんらかのロック メカニズムを使用して、リソースにアクセスできないことを子プロセスに通知することをお勧めします。

于 2012-07-21T18:05:51.723 に答える
0

もう一度ありがとうございます。最初のアプローチの結果を以下に示します

public class Component
{
    public ComponentPart SomeComponentPart1 { get; private set; }
    public ComponentPart SomeComponentPart2 { get; private set; }

    public Component()
    {
        SomeComponentPart1 = new ComponentPart(this);
        SomeComponentPart2 = new ComponentPart(this);
    }

    public bool IsMethodCallAcceptable(MethodCallExpression method, object[] parameters)
    {
        // collect needed information about caller
        var caller = (method.Object as ConstantExpression).Value;
        var methodName = method.Method.Name;
        var paramsArray = new Dictionary<string, object>();

        for (int i = 0; i < method.Arguments.Count; i++)
            paramsArray.Add((method.Arguments[i] as MemberExpression).Member.Name, parameters[i]);

        // make corresponding decisions
        if (caller == SomeComponentPart2)
            if (methodName == "SomeMethod")
                if ((int) paramsArray["intArg"] == 0 || (string) paramsArray["stringArg"] == "")
                    return false;

        return true;
    }
}

public class ComponentPart
{
    private Component Owner { get; set; }

    public ComponentPart(Component owner)
    {
        Owner = owner;
    }

    public int SomeMethod(int intArg, string stringArg)
    {
        // check if the method call with provided parameters is acceptable
        Expression<Func<int, string, int>> expr = (i, s) => SomeMethod(intArg, stringArg);
        if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new object[] { intArg, stringArg }))
            throw new Exception();

        // do some work
        return stringArg.Length + intArg;
    }

    public void AnotherMethod(bool boolArg, Dictionary<Guid, DateTime> crazyArg, string stringArg, object objectArg)
    {
        // check if the method call with provided parameters is acceptable
        Expression<Action<bool, Dictionary<Guid, DateTime>, string, object>> expr =
            (b, times, arg3, arg4) => AnotherMethod(boolArg, crazyArg, stringArg, objectArg);
        if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new [] { boolArg, crazyArg, stringArg, objectArg }))
            throw new Exception();

        // do some work
        var g = new Guid();
        var d = DateTime.UtcNow;
    }
}

これは、メソッド呼び出しを確認する方法のバリエーションです。プロパティ値の変更を確認するために同じアプローチを使用できますが、一部の ComponentPart のメソッドとプロパティは、Component.IsMethodCallAcceptable を呼び出す代わりに、(ComponentPart.Owner を介して) public Component.State プロパティを確認できます。またはComponent.IsPropertyChangeAcceptable。

于 2012-07-22T09:44:26.980 に答える