How to enforce private method since interface methods are only public?
Asked Answered
S

6

5

Interface can be used to force methods implementations but they need to be public.

What if I want to enforce private methods then ?

Update: It's not about preventing to call, it's about ensuring that the private method has been IMPLEMENTED.

So I don't want to use interface per se. I want to impose some style of coding to a team.

Sherris answered 23/4, 2011 at 16:49 Comment(5)
It doesn't make sense. If you want to prevent anybody but your own class from calling the method then just remove the method from the interface. And write a private method.Forestall
It's not about preventing to call, it's about ensuring that the private method has been IMPLEMENTED.Sherris
The only thing that can call a private method is your code... put a call from your class to the private method you're talking about... if it's not been implemented, it won't compile?!?Nubilous
why do you care if a private method has been implemented? I don't think you want an interface to do what you are trying to do.Apocalyptic
Not obligatory my code : it maybe someone else who code but you wants him to respect some style of coding.Sherris
M
10

Interfaces are always by definition public. The only way to enforce the implementation of a protected (private to the outside but accessible to derived classes) method is by subclassing an abstract class that defines that method:

public abstract class A
{
    protected abstract void Foo();
}

public class B : A
{
    protected override void Foo() { }
}

The above will break if you are trying to change Foo's access modifier in B, or forget to provide an implementation for Foo() in B.

Edit:

I believe achieving something close to what you want is possible using a nested class that is only visible to the outside class: This would allow using the private fields of the outer class and at the same time enforcing the implementation of an interface while technically the class is not visible from anywhere else:

public interface IFooWorker
{
    void DoWork();
    int CalculateSomething();
}

public class Foo
{
    private FooWorker _worker;
    private int _currentValue;
    private string _workStatement;


    public Foo()
    {
        _worker = new FooWorker(this);
    }

    private class FooWorker : IFooWorker
    {
        private Foo _outer;
        public FooWorker(Foo foo)
        {
            _outer = foo;
        }

        public void DoWork()
        {
            _outer._currentValue = CalculateSomething();
            _outer._workStatement = "I did work";
        }

        public int CalculateSomething()
        {
            return 42;
        }
    }

}
Mortality answered 23/4, 2011 at 16:55 Comment(4)
How do you do if your class is already inheriting from a concrete class (for example UserControl) ?Sherris
@user310291: You can't - an alternative would be composition instead of inheritance, but that might not be what you want since you still can only access the public methods of the class you access.Mortality
Then maybe using this ? #5766666Sherris
@user, you can insert a middle tier class. For example class Foo is somewhere you can't modify. You can create public abstract class MyFoo : Foo to add an abstract protected member, and then the more derived classes inherit from MyFoo and provide the implementation.Copula
A
4

why would you be dictating private methods through an interface? the individual classes should be black boxes, the interface only defines the public access to that class and should not be concerned with the private internals of that class, only that the public methods work in an intelligent way. So, I guess what I'm saying is don't even think about it, because it's a ludicrous concept that completely goes against what this feature of the language is trying to accomplish.

Apocalyptic answered 23/4, 2011 at 17:1 Comment(1)
I don't want to use interface per se. I want to impose some style of coding to a team.Sherris
P
2

For all intents and purposes, the private method does not exist for code outside of the class that contains it. It can be found via reflection, but...the entire meaning of private scoping is something that isn't part of the objects API. A private member is explicitly not part of the objects contract, it's something encapsulated within it.

Why are you trying to force other developers to "follow a coding style" to that level of granularity? What's the intended purpose or desired outcome?

Coming at this from another direction, you've said a couple of times you want to "make sure the method is implemented", or something to that effect.

If you want to act on a specific method's signature, and ensure that it is implemented, you could use a delegate / Func / Action and have the outer code inject in it's corresponding implementation. Your inner code can check if it's been provided and invoke if it has. You know that a method exists to handle the call as you have been provided a reference to it...i.e. you know that a corresponding method has been implemented somewhere.

If you have a straightforward situation and you're bubbling up from the inner logic to the outer logic, you can just use events. Create your event args to contain whatever you need to provide to attached handlers, use the generic event handler, and declare an event in your inner logic that you raise if it's not null when you need to pass control to the outer logic's implemented method. The outer logic hooks the event in the normal fashion and does whatever is appropriate to their usage. The event model is contractual, is very natural to .NET, is used prevalently, is easy to use, and many developers are very familiar with the pattern and know how to slot into it.

The "private" method contract you are intent on is unlikely to bear fruit for you and is counter to OO design, in my opinion.

Good luck!

Plexiglas answered 23/4, 2011 at 19:31 Comment(0)
D
1

It won't be "private", but you can still fake it with explicit interface implementation.

See this: http://msdn.microsoft.com/en-us/library/ms173157.aspx

Nothing would prevent someone from calling your method directly by upcasting to the interface type, though. Then again, private methods are implementation details: they don't belong in an interface.

Dinsmore answered 23/4, 2011 at 16:50 Comment(2)
I really don't want public, I want to be sure that the private method is implemented.Sherris
They, perhaps you need to make an abstract class and make that method protected.Dinsmore
D
1

By definition, Interfaces are sets of public methods. Perhaps you want an abstract class.

Deepsea answered 23/4, 2011 at 16:53 Comment(0)
G
0

That wouldn't make sense, because a private method declared in an interface could not be called.

Graehme answered 23/4, 2011 at 16:50 Comment(2)
I don't want to use interface, I want to be sure the private method exists.Sherris
What use is a method that cannot be called? Perhaps it would make sense to post a concrete example. I think I'm not the only one confused.Graehme

© 2022 - 2024 — McMap. All rights reserved.