0

I need to examine in "parent" object is there an acceptable at a definite moment to call some method in the "child". For example, parent object (component) includes child objects (or component parts in other words) and parent is disposing now, so all (or particlar) child activities must be prohibited (i.e. starting new service threads, enqueueing new client requests, ...).

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 ...
        ...            
    }
}

Is there any way to do it?

3
  • Thank to all respectable participants of conversation. May be due to lack of experience in English I have used some terms in the incorrect manner. Commented Jul 21, 2012 at 18:48
  • The subject isn't the relations between parent in child classes (OOP paradigm) but is the relations between separate parts of an component & the general component code. For example, we have a component CAR, which consist of four WHEELs, one ENGINE and so on. We can call CAR.ENGINE.START, but if the CAR.FUEL_TANK.GASOLINE_VOLUME = 0, our CAR can't move, so start of it's engine would be incorrect. So I need to check component's parts method calls and my CAR knows enough ebout these methods. Commented Jul 21, 2012 at 18:57
  • Now using of the delegates looks most acceptable, thank you, Haedrian. But I need to write a lot of delegates, while want to write one universal check method. Commented Jul 21, 2012 at 18:59

6 Answers 6

6

Note: I am answering your question, not your title. Others have answered the title.

Some objects have an isDisposed property, if your parent implements that and that is the only time you don't want to call methods, then yes. Otherwise no. If you control the source for the parent, you could add a property that does what you want.

If you don't control the source and you want to check more than isDisposed or the parent doesn't implement isDisposed, you might be able to check publicly exposed properties, but generally you should assume that if a method is exposed to the public, that it is acceptable to call it at any time. If you're calling private methods via reflection, then you're taking chances.

Edit in response to comment: Given your description, delegates won't give you any additional capability that you can't do easier by adding properties and methods to the parent (if you don't control the source, they won't help at all). The best method for dealing with your described scenario (CAR.ENGINE.START when out of gas, is for the Start method to either throw an exception or return a value indicationg the result of the attempt to start the engine).

Sign up to request clarification or add additional context in comments.

Comments

2

Use delegates?

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

3 Comments

Nice answer although a little bit short
@jclozano - Yeah I'd like to help more but I'm not so experienced with them. Hopefully someone will be able to help better, but at least this gets him/her pointed at the right direction.
Delegates can be used as a way to invoke a particular method; however, how can the Parent tell which Child Method is the target of the delegate? Is this information even part of the delegate (created from a Method Group)?
0

The easiest way is to pass an URI instead of a reference:

"NS.Child.ThirdMethod" for example.

Otherwise, a delegate is what is the closest to a function reference. You can pass that if you want.

However, this method is not compliant with OOP conception rules: Base class should know nothing about its children classes. It's better to use some kind of locking mechanism to tell the children that they can't have access to the resources.

Comments

0

use func Func<T, TResult> link

Comments

0

If these methods are native to the child class, the parent can't know anything about them for sure. Rice's Theorem will cause you all kinds of problems, if you could even see the code. Same problem (but to a lesser degree) if they're native to the parent class and are being overridden in the child, since you can't really guarantee that the child class will be doing everything (and only those things) that the parent class does; in fact, you can all but guarantee it will do something different. (If it didn't, why override?)

If they're native to the parent class and not overridable in the child, then just check whether the object is in a valid state for doing such a thing and throw an exception if it isn't.

As far as the actual validity check, for your example you can have a method like bool IsDisposing(); for other cases, you might keep track of the state in some other way. A private method like CanDoThisThing() might help, for example. Having a method that takes a generic operation name (not an operation; we already established the infeasibility of that) seems kinda broken to me.

2 Comments

The code doesn't show any inheritance, but if the child was derived from the parent, then it could know it was being disposed.
@jmoreno: It could, but it couldn't know if "this method is appropriate" (with variable method and args and everything) without knowing the parent's state and making that decision itself. About all it could know, without breaking encapsulation all to hell, is whether it's disposed -- and even exposing that much is iffy and smells of brokenness to me. (If your object is disposed...why in the 53462 hells do you still even have it around, let alone use it? If it's built in such a way that you can...why is it disposable?)
0

Thank you all again, the result in the first approach is listed below

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;
    }
}

This is variant how to check method calls, the same approach can be used in order to check properties values changes, while some ComponentPart' methods and properties can check some public Component.State property (via ComponentPart.Owner) instead of calling Component.IsMethodCallAcceptable or Component.IsPropertyChangeAcceptable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.