Protecting classes

D

David

Hi,

I want to be able to make a class only visible within the namespace, i.e.
only other classes within the namespace will have access to it.

I have tried putting a protected keyword against it. That doesn't work.

I have tried nesting it inside the class where I want to use it, this sort
of compiles, except some of my methods that rely on the class have
"Inconsistent accessibility:"

Here is an example...

public class Folders
{

class FolderChild
{
}

public static FolderChild[] GetFolders()
{
}

}

Basically, I don't want FolderChild to be visible to anything else except
Folders and its methods. How can I do that?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
J

Jon Skeet [C# MVP]

David said:
I want to be able to make a class only visible within the namespace, i.e.
only other classes within the namespace will have access to it.

You can't - there's no such access level in .NET.
 
D

Dave Sexton

Hi,
Basically, I don't want FolderChild to be visible to anything else except
Folders and its methods. How can I do that?

Then why is the static method that returns an array of FolderChild objects
public? That means that FolderChild must be visible to all assemblies.
Make the method private, since your code example already accomplishes your
goal of having FolderChild only visible to the Folders class - FolderChild
is a private, nested class.

--
Dave Sexton
http://davesexton.com/blog

David said:
Hi,

I want to be able to make a class only visible within the namespace, i.e.
only other classes within the namespace will have access to it.

I have tried putting a protected keyword against it. That doesn't work.

I have tried nesting it inside the class where I want to use it, this sort
of compiles, except some of my methods that rely on the class have
"Inconsistent accessibility:"

Here is an example...

public class Folders
{

class FolderChild
{
}

public static FolderChild[] GetFolders()
{
}

}

Basically, I don't want FolderChild to be visible to anything else except
Folders and its methods. How can I do that?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
D

David

Hi,

This has confused me now...

The FolderChild[] GetFolders needs to be accessible from outside the class
(so that I can do Folders.GetFolders() ). As you can see, the FolderChild
is actually a class that handles an array, and I don't want direct access to
that (from the outside, the array could be manipulated directly, which is
not what I want.)

I may have misunderstood. If I have, can you expand what you mean?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available

Dave Sexton said:
Hi,
Basically, I don't want FolderChild to be visible to anything else except
Folders and its methods. How can I do that?

Then why is the static method that returns an array of FolderChild objects
public? That means that FolderChild must be visible to all assemblies.
Make the method private, since your code example already accomplishes your
goal of having FolderChild only visible to the Folders class - FolderChild
is a private, nested class.

--
Dave Sexton
http://davesexton.com/blog

David said:
Hi,

I want to be able to make a class only visible within the namespace, i.e.
only other classes within the namespace will have access to it.

I have tried putting a protected keyword against it. That doesn't work.

I have tried nesting it inside the class where I want to use it, this
sort of compiles, except some of my methods that rely on the class have
"Inconsistent accessibility:"

Here is an example...

public class Folders
{

class FolderChild
{
}

public static FolderChild[] GetFolders()
{
}

}

Basically, I don't want FolderChild to be visible to anything else except
Folders and its methods. How can I do that?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
D

Daniel

Hi David,

If that is the only reason why you want this unusual requirement then its a
easy solution.

Make a method in the class that returns Folders.GetFolders() which is public
.. All other methods and the array make private

Now no outside class will be able to get or access the array directly, and
you can still get the things you need.


David said:
Hi,

This has confused me now...

The FolderChild[] GetFolders needs to be accessible from outside the class
(so that I can do Folders.GetFolders() ). As you can see, the FolderChild
is actually a class that handles an array, and I don't want direct access
to that (from the outside, the array could be manipulated directly, which
is not what I want.)

I may have misunderstood. If I have, can you expand what you mean?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available

Dave Sexton said:
Hi,
Basically, I don't want FolderChild to be visible to anything else
except Folders and its methods. How can I do that?

Then why is the static method that returns an array of FolderChild
objects public? That means that FolderChild must be visible to all
assemblies. Make the method private, since your code example already
accomplishes your goal of having FolderChild only visible to the Folders
class - FolderChild is a private, nested class.

--
Dave Sexton
http://davesexton.com/blog

David said:
Hi,

I want to be able to make a class only visible within the namespace,
i.e. only other classes within the namespace will have access to it.

I have tried putting a protected keyword against it. That doesn't work.

I have tried nesting it inside the class where I want to use it, this
sort of compiles, except some of my methods that rely on the class have
"Inconsistent accessibility:"

Here is an example...

public class Folders
{

class FolderChild
{
}

public static FolderChild[] GetFolders()
{
}

}

Basically, I don't want FolderChild to be visible to anything else
except Folders and its methods. How can I do that?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
D

Dave Sexton

Hi David,
The FolderChild[] GetFolders needs to be accessible from outside the class
(so that I can do Folders.GetFolders() ).

That means that the FolderChild class must have public access too. If it
doesn't, then how could you return an array of FolderChild objects from a
public method? This is what the compiler is complaining about. Either the
static method must be private or the FolderChild class must be public.
As you can see, the FolderChild is actually a class that handles an array,
and I don't want direct access to that (from the outside, the array could
be manipulated directly, which is not what I want.)

Actually, your code shows me that the FolderChild class has no members and a
public, static method returns an array of FolderChild instances. I think
you may want to just make the FolderChild class public if you need to access
it from the "outside". Otherwise, Daniel's suggestion to make it private
and provide a public wrapper is a good one, but you'll have to return
IEnumerable<Folder> or something like that.

Anyway, why does your Folder class need a FolderChild class? Can't Folder
just return a list of Folders?

2.0 Framework example:

class Folder
{
public IEnumerable<Folder> Folders
{
get
{
foreach (Folder folder in GetFoldersSomehow())
yield return folder;
}
}
}

BTW, arrays are immutable, so you wouldn't have to worry about a caller
manipulating the returned FolderChild[] if you decide to stick with that
route. However, your FolderChild classes within the array might be mutable,
depending upon your design, but you should try to make them immutable since
its a nested class (in which case it probably shouldn't be public or else
shouldn't be nested in the first place).

--
Dave Sexton
http://davesexton.com/blog

David said:
Hi,

This has confused me now...

The FolderChild[] GetFolders needs to be accessible from outside the class
(so that I can do Folders.GetFolders() ). As you can see, the FolderChild
is actually a class that handles an array, and I don't want direct access
to that (from the outside, the array could be manipulated directly, which
is not what I want.)

I may have misunderstood. If I have, can you expand what you mean?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available

Dave Sexton said:
Hi,
Basically, I don't want FolderChild to be visible to anything else
except Folders and its methods. How can I do that?

Then why is the static method that returns an array of FolderChild
objects public? That means that FolderChild must be visible to all
assemblies. Make the method private, since your code example already
accomplishes your goal of having FolderChild only visible to the Folders
class - FolderChild is a private, nested class.

--
Dave Sexton
http://davesexton.com/blog

David said:
Hi,

I want to be able to make a class only visible within the namespace,
i.e. only other classes within the namespace will have access to it.

I have tried putting a protected keyword against it. That doesn't work.

I have tried nesting it inside the class where I want to use it, this
sort of compiles, except some of my methods that rely on the class have
"Inconsistent accessibility:"

Here is an example...

public class Folders
{

class FolderChild
{
}

public static FolderChild[] GetFolders()
{
}

}

Basically, I don't want FolderChild to be visible to anything else
except Folders and its methods. How can I do that?

Thanks.

Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
J

Jesse McGrew

Dave Sexton wrote:
[...]
BTW, arrays are immutable, so you wouldn't have to worry about a caller
manipulating the returned FolderChild[] if you decide to stick with that
route. However, your FolderChild classes within the array might be mutable,
depending upon your design, but you should try to make them immutable since
its a nested class (in which case it probably shouldn't be public or else
shouldn't be nested in the first place).

Er... since when are arrays immutable? The caller couldn't change the
*length* of the array, but he could certainly change the contents.

Jesse
 
D

Dave Sexton

Hi Jesse,

Lol - that's embarrassing. I didn't think that through all the way - thanks
for correcting me :)

If the OP wants immutability then a generic ReadOnlyCollection should be
returned instead of an Array.

--
Dave Sexton
http://davesexton.com/blog

Jesse McGrew said:
Dave Sexton wrote:
[...]
BTW, arrays are immutable, so you wouldn't have to worry about a caller
manipulating the returned FolderChild[] if you decide to stick with that
route. However, your FolderChild classes within the array might be
mutable,
depending upon your design, but you should try to make them immutable
since
its a nested class (in which case it probably shouldn't be public or else
shouldn't be nested in the first place).

Er... since when are arrays immutable? The caller couldn't change the
*length* of the array, but he could certainly change the contents.

Jesse
 
D

David

Hi all that have responded. Thank you for taking the time to help me.

I am using C# 1.1.

I have been developing with C# for a couple of years, after coming from a
Classic ASP background of which was 6 years. What I am trying to say is that
whilst I am confident in programming, I am really pushing my boundaries with
this self imposed project. This may make me appear a little slow to
understand what is coming across.

I did note that the sample was in .NET 2.0 with the IEnumerable<Folder>,
which of course, I can't use at the moment.

Back to earlier comments in the thread...

The method from Daniel, I am not sure how to approach. An example will help.

Info from Dave Sexton with the 2.0 framework example, I didn't give all the
code. My FolderChild class has a public constructor which reads a DataRow,
which populates private variables, which are accessed through public
properties...

e.g.

public class FolderChild
{
// Private variables.
private string MyPrivateVar;
...

public FolderChild(object drObj)
{
// Populate the private variables.
MyPrivateVar = WhateverFromDataRow;
}

public string MyVar
{
get { return MyPrivateVar; }
}

}

The idea being to use it as....

foreach (Folder fd in Folder.GetFolders())
{
Response.Write(fd.MyVar);
}

At the moment, this class is not nested. It doesn't need to be nested, just
made so that accessibility to it is not easily available. It is not too big
a deal if it is accessible, as even if it was used improperly, hardly
anything will come of it. It will just make a "virtual" FolderChild which
cannot really be used without the backend support. All I am just trying to
do is to try and remove the possibility of accidental misuse which will lead
to unnecessary support calls. I guess I will have to put in comments in the
code documentation to steer future developers from using it.

Best regards,
Dave Colliver.
http://www.LeedsFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
Dave Sexton said:
Hi Jesse,

Lol - that's embarrassing. I didn't think that through all the way -
thanks for correcting me :)

If the OP wants immutability then a generic ReadOnlyCollection should be
returned instead of an Array.

--
Dave Sexton
http://davesexton.com/blog

Jesse McGrew said:
Dave Sexton wrote:
[...]
BTW, arrays are immutable, so you wouldn't have to worry about a caller
manipulating the returned FolderChild[] if you decide to stick with that
route. However, your FolderChild classes within the array might be
mutable,
depending upon your design, but you should try to make them immutable
since
its a nested class (in which case it probably shouldn't be public or
else
shouldn't be nested in the first place).

Er... since when are arrays immutable? The caller couldn't change the
*length* of the array, but he could certainly change the contents.

Jesse
 
D

Dave Sexton

Hi David,

Info from Dave Sexton with the 2.0 framework example, I didn't give all
the code. My FolderChild class has a public constructor which reads a
DataRow, which populates private variables, which are accessed through
public properties...

e.g.

public class FolderChild
{
// Private variables.
private string MyPrivateVar;
...

public FolderChild(object drObj)
{
// Populate the private variables.
MyPrivateVar = WhateverFromDataRow;
}

public string MyVar
{
get { return MyPrivateVar; }
}

}

The idea being to use it as....

foreach (Folder fd in Folder.GetFolders())
{
Response.Write(fd.MyVar);
}

But FolderChild cannot be coerced into a Folder unless it derives from
Folder, which it doesn't in your examples. And if it derives from Folder,
then you should probably just use Folder instead. My example used generics,
but it's not necessary at all if you're using an earlier version of the .NET
Framework. For instance, you can return an ICollection, IEnumerable,
ArrayList or an Array as in your original example. The point is to only use
one class that aggregates a collection of itself. In other words, unless
you have specific semantics or functionality to be encapsulated in a
"FolderChild" class, it isn't useful at all.

Here's an example that assumes you have created a strong-typed collection
that implements the ICollection interface. It's your choice whether you
want to make the implementation a read-only collection:

public class FolderCollection : ICollection
{
...
}

public class Folder
{
public string Name { get { return name; } }

public FolderCollection GetFolders()
{
get { return folders; }
}

private readonly string name;
private readonly FolderCollection folders;

public Folder()
{
// assuming your FolderCollection class takes the "owner"
// as a parameter...
folders = new FolderCollection(this);
}

public Folder(DataRow row)
: this()
{
name = row["Name"] as string;

// TODO: you may want to fill the folders collection here
}
}


This way, you can have an unlimited chain of Folders, not just a single
level deep as in your examples.
At the moment, this class is not nested. It doesn't need to be nested,
just made so that accessibility to it is not easily available. It is not
too big a deal if it is accessible, as even if it was used improperly,
hardly anything will come of it. It will just make a "virtual" FolderChild
which cannot really be used without the backend support. All I am just
trying to do is to try and remove the possibility of accidental misuse
which will lead to unnecessary support calls. I guess I will have to put
in comments in the code documentation to steer future developers from
using it.

I suspect that the FolderChild class isn't necessary at all. (see above)
 
K

KWienhold

I'm not quite sure I understand your problem correctly, but to answer
your initial question, the internal keyword should make objects
invisible to anything outside their namespace.


Sincerely,
Kevin Wienhold
 
M

Marc Gravell

internal applies to assemblies, not namespaces; It sounds like (as the
example shows) you want FolderChild to be private - but in this case
you can't have it as the return value from a public method, as how
would the caller use it? It can't see FolderChild!

Do you mean that the external caller should be able to see the object
but not create them? In this case, perhaps make the FolderChild class
public with an internal constructor? Or alternatively consider an
interface / base class so the caller knows about the properties but
not the FolderChild class (but this seems overkill).

Marc
 
J

Jon Skeet [C# MVP]

KWienhold said:
I'm not quite sure I understand your problem correctly, but to answer
your initial question, the internal keyword should make objects
invisible to anything outside their namespace.

No, internal restricts visibility to the *assembly*, which is not the
same as the namespace.
 

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