Enhancement idea: Private interfaces?

G

Guest

I know this sounds contrary to the idea of an interface, but read this and
see what you think
-----------------------------------------------------------------------------------------
It would be nice if there was a way for a class to create a special type of
interface, a private one. Private meaning it's not directly exposed at the
class level, you need to be explicitly handed a reference to it by the class.
Often the encapsulation issue is you need to implement an interface (as a
callback or some other functionality is required), but doing so exposes all
of those interface methods to any user of your class, breaking encapsulation.
So the only alternative is to then have an internal proxy class implement the
interface and proxy all of the calls to that. This would be much easier of a
class can implement a private interface that could selectively be handed out.
This way the integrity of the encapsulation is protected without requiring
the user to write a proxy class.


An example might be something like (I'm sure there could be better syntax):

public interface IMyInterface
{
void Callback();
}

class MyInterfaceUser
{
public void SetUseInterface(IMyInterface usethis)
{
// ...
{
}


class MyClass : private IMyInterface
{
MyClass(MyInterfaceUser user)
{
user.SetUseInterface(this.PrivateInterface(IMyInterface));

}

protected void Callback()
{
//...
}

}
 
W

William Stacey [MVP]

Why not use the factory pattern and inheritance? Return the derived type
(with the additional members) in the CreateX() method.

--
William Stacey [MVP]

|I know this sounds contrary to the idea of an interface, but read this and
| see what you think.
| -----------------------------------------------------------------------------------------
| It would be nice if there was a way for a class to create a special type
of
| interface, a private one. Private meaning it's not directly exposed at the
| class level, you need to be explicitly handed a reference to it by the
class.
| Often the encapsulation issue is you need to implement an interface (as a
| callback or some other functionality is required), but doing so exposes
all
| of those interface methods to any user of your class, breaking
encapsulation.
| So the only alternative is to then have an internal proxy class implement
the
| interface and proxy all of the calls to that. This would be much easier of
a
| class can implement a private interface that could selectively be handed
out.
| This way the integrity of the encapsulation is protected without requiring
| the user to write a proxy class.
|
|
| An example might be something like (I'm sure there could be better
syntax):
|
| public interface IMyInterface
| {
| void Callback();
| }
|
| class MyInterfaceUser
| {
| public void SetUseInterface(IMyInterface usethis)
| {
| // ...
| {
| }
|
|
| class MyClass : private IMyInterface
| {
| MyClass(MyInterfaceUser user)
| {
| user.SetUseInterface(this.PrivateInterface(IMyInterface));
|
| }
|
| protected void Callback()
| {
| //...
| }
|
| }
|
 
G

Guest

Certainly proxies or factory patterns work, but that means you now have to
make anyone that uses your class go through a special factory just because
you don't want to expose a particular interface, that just seems plain not
good from the stand point of someone going to use the class.

It would be much cleaner to be able to avoid extra proxy method hops and
special patterns for usage of your class, by having this mechanism.
 
W

William Stacey [MVP]

Not sure I follow. Just return the base class and the user uses that. Then
for internal usage, just cast it to lower class and use it. The user will
not see your "special" methods.

public class UserClass
{
private UserClass()
{
}
public static UserClass Create()
{
PowerClass ic = new PowerClass();
return (UserClass)ic;
}
public string Name = "Santa";


public static void DoSpecialWork(UserClass uc)
{
((PowerClass)uc).DoThis();
}

private class PowerClass : UserClass
{
public string SpecialName = "Saint Nick";
public void DoThis()
{
Console.WriteLine("I did that.");
}
}
}

// Test
UserClass uc = UserClass.Create();
UserClass.DoSpecialWork(uc);

--
William Stacey [MVP]

| Certainly proxies or factory patterns work, but that means you now have to
| make anyone that uses your class go through a special factory just because
| you don't want to expose a particular interface, that just seems plain not
| good from the stand point of someone going to use the class.
|
| It would be much cleaner to be able to avoid extra proxy method hops and
| special patterns for usage of your class, by having this mechanism.
|
|
|
| "William Stacey [MVP]" wrote:
|
| > Why not use the factory pattern and inheritance? Return the derived
type
| > (with the additional members) in the CreateX() method.
| >
| > --
| > William Stacey [MVP]
| >
| > | > |I know this sounds contrary to the idea of an interface, but read this
and
| > | see what you think.
| >
| -----------------------------------------------------------------------------------------
| > | It would be nice if there was a way for a class to create a special
type
| > of
| > | interface, a private one. Private meaning it's not directly exposed at
the
| > | class level, you need to be explicitly handed a reference to it by the
| > class.
| > | Often the encapsulation issue is you need to implement an interface
(as a
| > | callback or some other functionality is required), but doing so
exposes
| > all
| > | of those interface methods to any user of your class, breaking
| > encapsulation.
| > | So the only alternative is to then have an internal proxy class
implement
| > the
| > | interface and proxy all of the calls to that. This would be much
easier of
| > a
| > | class can implement a private interface that could selectively be
handed
| > out.
| > | This way the integrity of the encapsulation is protected without
requiring
| > | the user to write a proxy class.
| > |
| > |
| > | An example might be something like (I'm sure there could be better
| > syntax):
| > |
| > | public interface IMyInterface
| > | {
| > | void Callback();
| > | }
| > |
| > | class MyInterfaceUser
| > | {
| > | public void SetUseInterface(IMyInterface usethis)
| > | {
| > | // ...
| > | {
| > | }
| > |
| > |
| > | class MyClass : private IMyInterface
| > | {
| > | MyClass(MyInterfaceUser user)
| > | {
| > | user.SetUseInterface(this.PrivateInterface(IMyInterface));
| > |
| > | }
| > |
| > | protected void Callback()
| > | {
| > | //...
| > | }
| > |
| > | }
| > |
| >
| >
| >
 
G

Guest

You didn't actually use an interface there but same general idea.
I see a few concerns with that:
1. The "interface" is still accessible externally, they could cast the class
to the power class (unless the power class was internal/private)
2. It requires me as the class developer to create two classes just to hide
my interface
3. It requires me as the user of the component to know that I must call
UserClass.Create() rather than just being able to do new UserClass(); Forcing
the user to use a .Create method rather than a "new" just because you want to
hide an internal interface seems like it doesn't really deserve a factory
pattern and just feels wrong and makes usage of instantiation different for
that class just because the internal implementation needed to hide an
interface.

All of those add up to a less than desireable solution for both the
developer of the class and the user of the class. If you implemented the
private interface concept, the usage of creating the class can still use
"new" and the developer of the class did not have to create a derived class
just to hide the interface. Private interfaces produce truly encapsulated
private interfaces and easier to use code.
 
W

William Stacey [MVP]

I think I see what you need. Actually, c# has private interface ability
already. Example:

interface IPower
{
void DoIt();
}

public class UserClass : IPower
{
public string Name = "Santa";

public UserClass()
{
}

void IPower.DoIt()
{
Console.WriteLine("DoIt");
}

public static void Test()
{
UserClass uc = new UserClass();
IPower ip = (IPower)uc;
ip.DoIt();
}
}

A user could still use reflection to gain access to private members.

--
William Stacey [MVP]

|
| You didn't actually use an interface there but same general idea.
| I see a few concerns with that:
| 1. The "interface" is still accessible externally, they could cast the
class
| to the power class (unless the power class was internal/private)
| 2. It requires me as the class developer to create two classes just to
hide
| my interface
| 3. It requires me as the user of the component to know that I must call
| UserClass.Create() rather than just being able to do new UserClass();
Forcing
| the user to use a .Create method rather than a "new" just because you want
to
| hide an internal interface seems like it doesn't really deserve a factory
| pattern and just feels wrong and makes usage of instantiation different
for
| that class just because the internal implementation needed to hide an
| interface.
|
| All of those add up to a less than desireable solution for both the
| developer of the class and the user of the class. If you implemented the
| private interface concept, the usage of creating the class can still use
| "new" and the developer of the class did not have to create a derived
class
| just to hide the interface. Private interfaces produce truly encapsulated
| private interfaces and easier to use code.
|
| "William Stacey [MVP]" wrote:
|
| > Not sure I follow. Just return the base class and the user uses that.
Then
| > for internal usage, just cast it to lower class and use it. The user
will
| > not see your "special" methods.
| >
| > public class UserClass
| > {
| > private UserClass()
| > {
| > }
| > public static UserClass Create()
| > {
| > PowerClass ic = new PowerClass();
| > return (UserClass)ic;
| > }
| > public string Name = "Santa";
| >
| >
| > public static void DoSpecialWork(UserClass uc)
| > {
| > ((PowerClass)uc).DoThis();
| > }
| >
| > private class PowerClass : UserClass
| > {
| > public string SpecialName = "Saint Nick";
| > public void DoThis()
| > {
| > Console.WriteLine("I did that.");
| > }
| > }
| > }
| >
| > // Test
| > UserClass uc = UserClass.Create();
| > UserClass.DoSpecialWork(uc);
| >
| > --
| > William Stacey [MVP]
| >
| > | > | Certainly proxies or factory patterns work, but that means you now
have to
| > | make anyone that uses your class go through a special factory just
because
| > | you don't want to expose a particular interface, that just seems plain
not
| > | good from the stand point of someone going to use the class.
| > |
| > | It would be much cleaner to be able to avoid extra proxy method hops
and
| > | special patterns for usage of your class, by having this mechanism.
| > |
| > |
| > |
| > | "William Stacey [MVP]" wrote:
| > |
| > | > Why not use the factory pattern and inheritance? Return the derived
| > type
| > | > (with the additional members) in the CreateX() method.
| > | >
| > | > --
| > | > William Stacey [MVP]
| > | >
| > | > | > | > |I know this sounds contrary to the idea of an interface, but read
this
| > and
| > | > | see what you think.
| > | >
| >
| -----------------------------------------------------------------------------------------
| > | > | It would be nice if there was a way for a class to create a
special
| > type
| > | > of
| > | > | interface, a private one. Private meaning it's not directly
exposed at
| > the
| > | > | class level, you need to be explicitly handed a reference to it by
the
| > | > class.
| > | > | Often the encapsulation issue is you need to implement an
interface
| > (as a
| > | > | callback or some other functionality is required), but doing so
| > exposes
| > | > all
| > | > | of those interface methods to any user of your class, breaking
| > | > encapsulation.
| > | > | So the only alternative is to then have an internal proxy class
| > implement
| > | > the
| > | > | interface and proxy all of the calls to that. This would be much
| > easier of
| > | > a
| > | > | class can implement a private interface that could selectively be
| > handed
| > | > out.
| > | > | This way the integrity of the encapsulation is protected without
| > requiring
| > | > | the user to write a proxy class.
| > | > |
| > | > |
| > | > | An example might be something like (I'm sure there could be better
| > | > syntax):
| > | > |
| > | > | public interface IMyInterface
| > | > | {
| > | > | void Callback();
| > | > | }
| > | > |
| > | > | class MyInterfaceUser
| > | > | {
| > | > | public void SetUseInterface(IMyInterface usethis)
| > | > | {
| > | > | // ...
| > | > | {
| > | > | }
| > | > |
| > | > |
| > | > | class MyClass : private IMyInterface
| > | > | {
| > | > | MyClass(MyInterfaceUser user)
| > | > | {
| > | > | user.SetUseInterface(this.PrivateInterface(IMyInterface));
| > | > |
| > | > | }
| > | > |
| > | > | protected void Callback()
| > | > | {
| > | > | //...
| > | > | }
| > | > |
| > | > | }
| > | > |
| > | >
| > | >
| > | >
| >
| >
| >
 
G

Guest

Right, but I'm talking about a case where I may have to implement in my class
an interface that I don't control myself so I can not insure that it is
private. Let's say I have a routine I use internally that needs me to
implement INotMyInterface which is public. I don't control that interface
but I need to use it for a callback. I don't want the callback method it
exposes shown publicly from my class, so my choices are back to a
proxy/factory pattern which as I mentioned is detrimental for both the
implementer and the user of the class. Where if we could support "making"
any interface I derive from to be private I could prevent exposing the public
interface methods on my class, without having to resort to the not so good
solutions of proxy/factory patterns.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top