|
-
Jan 10th, 2007, 12:24 AM
#1
Thread Starter
Hyperactive Member
[2005] Need scope help.
I am making a dll that will only expose one top level class, but the lower classes can be accessed thru the top level class. I thought that I could make the lower level class Friends, and the top level class public. However, it seems that a friend class cannot be exposed outside of the calling class if the class is public.
How can I make a public class expose a class thru a property, but only thru that property?
Thank you for your help.
-
Jan 10th, 2007, 12:48 AM
#2
Thread Starter
Hyperactive Member
Re: [2005] Need scope help.
BTW, just so you don't think I am being lazy or stupid, I know about the five scope qualifiers, Public, Friend, Private, Protected, and Protected Friend. I just think I am missing something because if I make the lower level class public it will be exposed outside the project, and from what I read, I could do it with a nested class, but before I go that route, I want to make sure I am not misunderstanding something because it seems that the nested class is the only way to do it, but I don't like how that formats in my code. So, I am hoping I am wrong and possibly misunderstanding something.
Thank you for your help.
-
Jan 10th, 2007, 01:10 AM
#3
Re: [2005] Need scope help.
You declare the class itself Public but declare its constructor(s) Friend. That way you can have instances accessed from outside the assembly but not created. This is not an uncommon scenario.
-
Jan 10th, 2007, 01:23 AM
#4
Thread Starter
Hyperactive Member
Re: [2005] Need scope help.
That stopped me from creating an instance of it in a test project, but it still shows up in intellisense. Is there a way to prevent that from being shown?
Thank you for your help, jmcilhinney.
-
Jan 10th, 2007, 01:30 AM
#5
Re: [2005] Need scope help.
You don't want to prevent it being displayed by Intellisense because you have to be able to declare a variable of that type. If you try to write code that invokes a constructor though, the IDE will refuse to compile it. Take the DataRow as an example. It is listed by Intellisense and you often declare variables of that type, but you cannot create a new instance because there is no public constructor.
-
Jan 10th, 2007, 01:38 AM
#6
Thread Starter
Hyperactive Member
Re: [2005] Need scope help.
Yes, I didn't think about that. I guess what I was hoping for is to not expose it outside of my project since it can only be accessed thru the top level class ( I tend to be a bit anal about controlling things), but this works good in forcing it to be accessed thru the top level class, and that is what I was looking for. I could just add a description that says that it can't be instantiated outside the top level class.
Thanks again for your help.
-
Jan 10th, 2007, 01:45 AM
#7
Re: [2005] Need scope help.
Like I said, just because you can only get an instance initially through some other class is no reason to restrict access to the type itself. If the user wants to access multiple members of an instance they shouldn't have to access them all via some property, e.g.
VB Code:
Dim ut As New UnrestrictedType
ut.RestrictedType.Property1 = value1
ut.RestrictedType.Property2 = value2
They should be able to assign the value of the property to a local variable and then access its properties directly, e.g.
VB Code:
Dim ut As New UnrestrictedType
Dim rt As RestrictedType = ut.RestrictedType
rt.Property1 = value1
rt.Property2 = value2
To prevent that would be poor form and I doubt that it's even possible.
-
Jan 10th, 2007, 02:20 AM
#8
Thread Starter
Hyperactive Member
Re: [2005] Need scope help.
I see. I didn't know that. I will do it as suggested then. Unfortunantly, I can't seem to get to anything below the top level class.
Let me show you what I have.
VB Code:
Public Class ReportManager
Private _ReportTemplate As Template
Public Sub New()
_ReportTemplate = New Template
End Sub
Public ReadOnly Property ReportTemplate() As Template
Get
ReportTemplate = _ReportTemplate
End Get
End Property
End Class
Public Class Template
Friend _ReportDetails As Details
Friend _ReportCompetencies New Competencies
Friend Sub New()
_ReportDetails = New Details
_ReportCompetencies = New Competencies
End Sub
Public ReadOnly Property ReportDetails() As Details
Get
ReportDetails = _ReportDetails
End Get
End Property
Friend ReadOnly Property ReportFunctions() As Competencies
Get
ReportFunctions = _ReportCompetencies
End Get
End Property
End Class
Public Class Details
Private _ReportDetailsCollection As Collection
Friend Sub New()
_ReportDetailsCollection = New Collection
End Sub
Public ReadOnly Property ReportDetailsCount() As Int64
Get
Return _ReportDetailsCollection.Count
End Get
End Property
End Class
Then, in my test project I call it this way.
Public Class frmMain
Dim MyReport As New PEP.ReportControl.ReportManager
MyReport. <----no options here. EDIT: Line under it says, "Declaration expected."
End Class
I don't see what I am doing wrong.
Last edited by Krenshau; Jan 10th, 2007 at 02:34 AM.
-
Jan 10th, 2007, 02:35 AM
#9
Re: [2005] Need scope help.
You can't access members of an object outside a method like that. The only thing you can do outside a method is write a declaration. You must access members of an object either inside a method body or on the right hand side of an assignment that forms part of a variable declaration.
Also, please don't ever use the Collection class in VB.NET. It is a VB6 hold-over and should never be used in new code. .NET provides a plethora of options when it comes to collections. You should take a look at the System.Collections and System.Collections.Generic namespaces. I would also question your design. Your Template class having a property of type Details and Details having an internal collection is a faulty design in my opinion. It would be more proper to have a ReportDetail class and a ReportDetailCollection class derived from System.Collections.ObjectModel.Collection(Of ReportDetail). The Template class would then have a property named ReportDetails of type ReportDetailCollection.
-
Jan 10th, 2007, 03:12 AM
#10
Thread Starter
Hyperactive Member
Re: [2005] Need scope help.
Ok, you are talking a little bit over my head. Let me start with the design first because that is the most important. After reading your post over and over, I think I understand what you are saying. Are you saying that Details should not be a class holding a collection, the class should be a ReportDetailsCollection class that is derived from the system.collections namespace? If so, when you say derived, are you saying that it should be inherited? I have Visual Basic 2005: The Language so I will read over that section again. I think I skimmed it last time because it seemed complicated.
On the ReportDetails, this is a list of items such as Name, Date, Subject, and other things that the end user will enter at runtime so I have to store these so that when the end user uses this report template I will present the user with these and a text box for each so that the user can assign a value to each of the report details items. For example, when the user designs the report they add details that they want to have entered when using the report, then those details are displayed when the end user runs a report so a value can be assigned. Then, those details and values will be printed and/or saved in a database (the whole class will be saved, I will mark it serializable before I finish). I know I just repeated the same thing, but I tried to say it a little different in case I wasn't clear the first time.
On the first paragraph, I will have to think about what you are saying more. I think you are saying that I can't access subs, functions, and properties the way I did. If that is so, is that different than it was in VB6? I am pretty sure I did that in VB6, but of course, this isn't VB6.
Any clarification and/or letting me know if I am understanding what you are saying would be great.
As a side note, part of the reason I thought of this design was because it seemed to me to be similar to how the .NET framework was structured. In other words, the top class, the System class is broad, and then they narrow down after that. In my structure it would be ReportManager. Then, under that it would be the template and the data class. The Template class would store the report template, the details class, the competency class, the practices class, and the ratings class. Each of those would allow for their respective items to be added, removed, edited, and other manipulations. Under the Data class side would be data specific to the specific instance of the report being done for a particular person. In other words, the comments that the evaluator enters about a persons performance, and other things, each with its own class.
Ok, I think I have used up all the space in vbforums database. I am going to read more about the system.collections namespace and think more about the design. I will work on coming up with a more usable design. Thank you for taking the time to tell me that my design is bad. I am the only programmer, so it is nice to have someone to tell me I am wrong.
-
Jan 10th, 2007, 03:34 AM
#11
Re: [2005] Need scope help.
This code is wrong:
VB Code:
Public Class frmMain
Dim MyReport As New PEP.ReportControl.ReportManager
MyReport. <----no options here. EDIT: Line under it says, "Declaration expected."
End Class
You cannot simply access a member of MyReport out in the open like that. You can only access a member of MyReport if you're assigning it to a variable you just declared, e.g.
VB Code:
Public Class frmMain
Dim MyReport As New PEP.ReportControl.ReportManager
Dim MyTemplate As PEP.ReportControl.Template = MyReport.ReportTemplate
End Class
Otherwise you must access the members of MyReport inside a method.
On the subject of terminology, if you say "ClassA inherits ClassB" then you are saying the same thing with "ClassA is derived from ClassB".
On the subject of design, this would be considered bad design:
VB Code:
Public Class ClassA
Private _classB As ClassB
Public ReadOnly Property ClassB() As ClassB
Get
Return Me._classB
End Get
End Property
End Class
Public Class ClassB
Private items As List(Of Object)
'etc.
End Class
This would be considered good design:
VB Code:
Public Class ClassA
Private _classBs As ClassBCollection
Public ReadOnly Property ClassBs() As ClassBCollection
Get
Return Me._classBs
End Get
End Property
End Class
Public Class ClassB
'...
End Class
Public Class ClassBCollection
Inherits System.Collections.ObjectModel.Collection(Of ClassB)
'Add any additional required members here, although all standard
'collection members are inherited from Collection(Of T).
End Class
That's basically how properties that expose collections are implemented throughout the Framework.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|