I am trying to learn passing a list between two C# forms using constructors as shown below. On the first form I did:
List<Cat> myCatList;
//list populating function...
private void btnDisplay_Click(object sender, EventArgs e)
{
df = new DisplayForm(myCatList);
df.Show();
this.Hide();
}
On the next form, I tried to receive the data as shown below:
List<Cat> catList;
public DisplayForm(List<Cat> catList)
{
InitializeComponent();
this.catList = catList;
}
But I always get an error on the second form constructor saying:
Error 1 Inconsistent accessibility: parameter type 'System.Collections.Generic.List<_05_WindowsFormsAppCat.Cat>' is less accessible than method '_05_WindowsFormsAppCat.DisplayForm.DisplayForm(System.Collections.Generic.List<_05_WindowsFormsAppCat.Cat>)'
Any ideas?
The List part is a complete red herring here. You'd get exactly the same problem if your constructor had a Cat parameter instead of a List<Cat> parameter.
Your Cat type is probably internal, because you haven't declared it as public. Therefore you can't use it in the signature of a public member such as this:
public DisplayForm(List<Cat> catList)
Options:
Make Cat a public class
Make your DisplayForm constructor internal
Personally I'm all for keeping things as private as is practical - although for small projects it won't make much difference, particularly for apps which are just a single assembly anyway. Most developers tend to err on the side of making everything public, which is a mistake IMO, but it's a judgement call. Both of the above options will work fine... but you should at least think about whether you want any other assembly to know about the Cat type (or indeed whether you want code in other assemblies to be able to call that constructor).
Where did you declare the Cat class? It must be publicly accessible to the DisplayForm class. You may have to add the public keyword to its declaration.
This is known as the accessibility of a type or a member.
Here is a reference of the different levels and their default values:
http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
I'm guessing that your Cat type was either in another assembly (project) as your DisplayForm, in which case it was by default not visible to classes in that project, or that you defined it as a nested class of your first Form class which would have made it private and accessible in the scope of that Form.
Related
I'm trying to pass an object (a reference to the currently logged on user, basically) between two forms. At the moment, I have something along these lines in the login form:
private ACTInterface oActInterface;
public void button1_Click(object sender, EventArgs e)
{
oActInterface = new ACTInterface(#"\\actserver\Database\Premier.pad",this.textUser.Text,this.textPass.Text);
if (oActInterface.checkLoggedIn())
{
//user has authed against ACT, so we can carry on
clients oClientForm = new clients(oActInterface);
this.Hide();
oClientForm.Show();
}
else...
on the next form (clients), I have:
public partial class clients : Form
{
private ACTInterface oActInt {get; set;}
public clients(ACTInterface _oActInt)
...which results in me getting:
Error 1 Inconsistent accessibility:
parameter type 'support.ACTInterface' is less accessible than method
'support.clients.clients(support.ACTInterface)'
c:\work\net\backup\support\support\clients.cs 20 16 support
I don't really understand what the problem is - both fields are private, and accessed by the relevant public method from the form. Googling doesn't really help, as it just points towards one element being public and the other private, which isn't the case here.
Anybody help?
Constructor of public class clients is public but it has a parameter of type ACTInterface that is private (it is nested in a class?). You can't do that. You need to make ACTInterface at least as accessible as clients.
Make the class public.
class NewClass
{
}
is the same as:
internal class NewClass
{
}
so the class has to be public
If sounds like the type ACTInterface is not public, but is using the default accessibility of either internal (if it is top-level) or private (if it is nested in another type).
Giving the type the public modifier would fix it.
Another approach is to make both the type and the method internal, if that is your intent.
The issue is not the accessibility of the field (oActInterface), but rather of the type ACTInterface itself.
What is the accessibility of the type support.ACTInterface. The error suggests it is not public.
You cannot expose a public method signature where some of the parameter types of the signature are not public. It wouldn't be possible to call the method from outside since the caller couldn't construct the parameters required.
If you make support.ACTInterface public that will remove this error. Alternatively reduce the accessibility of the form method if possible.
parameter type 'support.ACTInterface' is less accessible than method
'support.clients.clients(support.ACTInterface)'
The error says 'support.ACTInterface' is less accessible because you have made the interface as private, at least make it internal or make it public.
The problem doesn't seem to be with the variable but rather with the declaration of ACTInterface. Is ACTInterface declared as internal by any chance?
When I received this error, I had a "helper" class that I did not declare as public that caused this issue inside of the class that used the "helper" class. Making the "helper" class public solved this error, as in:
public ServiceClass
{
public ServiceClass(HelperClass _helper)
{ }
}
public class HelperClass {} // Note the public HelperClass that solved my issue.
This may help someone else who encounters this.
You can get Parameter (class that have less accessibility) as object then convert it to your class by as keyword.
In my case I hadone class in a file and I was passing a instance of that class to the constructor of my form in another file.
The problem was had declared the class without the public modifier : class MyClass {}
I could have solved it by changing it to public class MyClass {}
If this error occurs when you want to use a classvariable in a new form, you should put the class definition in the
Formname.Designer.cs
instead of the Formname.cs file.
After updating my entity framework model, I found this error infecting several files in my solution. I simply right clicked on my .edmx file and my TT file and click "Run Custom Tool" and that had me right again after a restart of Visual Studio 2012.
All the answers that say make the type ActInterface as public are right. I am only putting this post to explicitly mention why that's an issue
If a parameter to your public class constructor is private or internal qualified class, it means you wont be able to create an object of that parameter class from outside of the assembly and when you cannot instantiate the parameter object, how can you call this constructor to instantiate an object of this class ?
Try making your constructor private like this:
private Foo newClass = new Foo();
cant quite understand how class work
class Class1{
private int a;
for(a=0;a<10;a++){}
// how can a be out of scope?
}
and why i can do this
class Class1{
private int a;
void tera()
{
private string aiha="lk"; //commenting this out ,makes it work why??
for(a=0;a<10;a++){}
}
}
1st part : can a class have only methods and fields? why?
2nd part: cant methods have declarations?
i know this might be a poor explanation but i cant wrap my head around .
For the first part, you haven't defined a method name so it wont work, you can't place the method's body inside a class without declaring a method.
class Class1{
private int a = 0;
void Example() {
for(a=0;a<10;a++){}
}
}
Would work
For the second part, it wouldn't make sense as variable is only available inside the method's scope so its meaningless to give it a modifier.
You can read more about classes here but basically its a group of members and methods that are usually gonna be used every time you create an instance of that class.
1st.
(Classes are basic constructs of .NET Framework.)
Because it's object oriented it can only contain MEMBERS like methods, fields, constants, properties, and events as single units .
(note: also members must be declared within a type).
2nd
In C# there are no global variables or methods as there are in some other languages.
and i think since c# considers a method as a single object you cannot try give different access to its variables, it will think you are trying to create another member for the class.
Doing an assignment that a teacher has pretty much wrote us step by step how to do, I've had these 4 errors for a while but just ignored them.
Basically i have a parent class Menus with child classes PauseMenu, MainMenu, DifficultyMenu, and HelpMenu. The four errors i am getting say that the parent class is less accessible than the child class. Menu is abstract while the child menus are public, as instructed.
#region Constructors
protected Menu(MenuName menuName, Texture2D background, Rectangle drawRectangle)
{
this.menuName = menuName;
this.background = background;
this.drawRectangle = drawRectangle;
}
public Menu()
{
}
#endregion
our professor specifically said to add a public constructor with no parameters specifically for this reason, but my IDE is still telling me that its wrong.
Any ideas on how to fix this?
Here is the constructor for the main menu
public MainMenu(Rectangle drawRectangle)
: base(MenuName.MainMenu, SpriteDictionary.GetSprite("mainMenuBackground"), drawRectangle)
{}
here is the declaration of the class
namespace WackyPong.Menus
{
public abstract class Menu
{
//all my code
}
This error is usually related to class accessibility, as mentioned in comments. This can cause a problem since you expose a derived type via public but not the base type, and thus typecasting and inherited members enter a grey area of "do we expose these to other dlls?" - an area eliminated by this error refusing to build your project.
Seeing that the abstract base class is indeed public, have you made sure this applied to all of the types you've created? I note the use of a MenuName object in the constructor.
Note that this error will also show up if you have any public properties, fields, or methods which take or return types which are not publicly exposed - the compiler again enters that area of "the member is exposed, but the type included in its signature isn't."
I have a couple of classes in my system
//this was not made an Interface for some WCF reasons
public abstract class BaseTransmission
{
protected internal abstract string Transmit();
//other common properties go here
}
And a few child classes like
public class EmailTransmission : BaseTransmission
{
//This property is added separately by each child class
public EmailMetadata Metadata { get; set; }
protected internal override string Transmit()
{
//verify email address or throw
if (!Metadata.VerifyMetadata())
{
throw new Exception();
}
}
}
Elsewhere, I have created a method with signature Transmit(BaseTransmission transmission). I am calling this method from another part of my code like this:
TransService svc = new TransService();
EmailTransmission emailTrans = new EmailTransmission(); // this inherits from BaseTransmission
svc.Transmit(emailTrans);
This solves my purpose. But usually when I see examples of polymorphism, I always see that the reference type is base class type and it points to an instance of child class type. So usually in typical examples of polymorphism
EmailTransmission emailTrans = new EmailTransmission();
will usually be
BaseTransmission emailTrans = new EmailTransmission();
I cannot do this because EmailTransmission EmailMetadata is different from lets say FaxMetadata. So if I declare the reference to be of BaseTranmission type and point it to an instance of EmailTranmission type, I lose access to the EmailMetadata property of the EmailTransmission.
I want to know whether what I am doing above is a misuse of polymorphism and whether it 'breaks' polymorphism in some way. And if it is abusing polymorphism, whats the right way to do this.
This is perfectly valid. The polymorphic pattern is used in the TransService service Transmit method.
It works with a class that can be morphed in one or more classes.
The fact that you declare the variable using the base class or the derived class is up to you and depends on your specific case.
That should be completely fine. Within the transmit method the object is referenced as BaseTransmission, the "downcasting" is therefore less obvious.
(had this as comment beforehand, but this should really be an answer)
Well, this is perfetly valid case: as you use base class type like a base parameter in the
TransService.Trasmit method.
The only thing which looks strange is:
protected internal abstract string Transmit();
do you really need protected and internal ?
If yes, just skip this notion.
Generally you would prefer using base type
BaseTransmission emailTrans = new EmailTransmission();
This keeps you abstraction clean and helps you with Don't Repeat Yourself. This will be useful in the following scenario: suppose a user can select how she/he can be contacted (email, fax, text). When you need to send something you just have a single method that takes BaseTransmission object and parameters, say BaseParameter.
Note: if it looks, as if there is not much code can be shared, you can define an interface ITransmitter and use it to show that a class can send something, like:
ITransmitter transmitter = new EmailTransmission();
What you are doing is absolutely correct and should work without issue. Passing a child class to a function/method that takes the base class should not be an issue.
However, regarding your example here:
This solves my purpose. But usually when I see examples of polymorphism, I always see that the reference type is base class type and it points to an instance of child class type. So usually in typical examples of polymorphism
EmailTransmission emailTrans = new EmailTransmission();
will usually be
BaseTransmission emailTrans = new EmailTransmission();
This is done if BaseTransmission is an interface or abstract class and you then need to construct a specific version of BaseTransmission. Sometimes if you don't need the extra components some people like to use this to keep their code clean as well. The most common usage of this is seen with generics such as when you want to create a List for example, but need to implement a specific version os List such as ArrayList or LinkedList
We have a Student class in our business model. something struck me as strange, if we are manipulating one student from another student, the students private members are visible, why is this?
class Program {
static void Main(string[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.SeePrivatePropertiesAndFields(s2);
}
}
public class Student {
private String _studentsPrivateField;
public Student() {
_studentsPrivateField = DateTime.Now.Ticks.ToString();
}
public void SeePrivatePropertiesAndFields(Student anotherStudent) {
//this seems like these should be private, even from the same class as it is a different instantiation
Console.WriteLine(anotherStudent._studentsPrivateField);
}
}
Can i have some thoughts on the design considerations/implications of this. It seems that you can't hide information from your siblings. Is there a way to mark a field or member as hidden from other instances of the same class?
There's an easy way to ensure this:
Don't mess around with private members of other instances of the same class.
Seriously - you're the one writing the Student code.
The easiest way to ensure this is to program to an interface, such as:
class Program
{
static void Main(string[] args)
{
IStudent s1 = new Student();
IStudent s2 = new Student();
s1.ExamineStudentsMembers(s1);
}
}
public interface IStudent
{
void ExamineStudentsMembers(IStudent anotherStudent);
}
public class Student : IStudent
{
private string _studentsPrivateMember;
public Student()
{
_studentsPrivateMember = DateTime.Now.Ticks.ToString();
}
public void ExamineStudentsMembers(IStudent anotherStudent)
{
Console.WriteLine(anotherStudent._studentsPrivateMember);
}
}
This will no longer compile due to ExamineStudentsMembers trying to access a private field.
If you are writing the class, you have complete control over it, so if you don't want one object to be able to modify another, don't write in that functionality.
Classes will often use private variables in other instances to implement efficient comparison and copy functions.
Private just means that the member (field/method/etc.) can be accessed only from the within the code of the parent type. From CSharpOnline
Private members of multiple instances are visible and can be invoked. This comes in handy when you are implementing a "copy constructor" or a "clone" method on your type, where the argument is an instance of the same type. If the designers would have made private fields inaccessible, then you may have to create a bunch of getter methods just for clone/copy to get at them. IMHO, I like it better the way it is. Within the same type, Reading another object's state isn't that bad as writing to it though (which could be a DONT-code-convention for you/your team.)
Accessing a sibling's private data may seem wrong when phrased like:
public void ExamineStudentsMembers(Student anotherStudent) {
//this seems very wrong
Console.WriteLine(anotherStudent._studentsPrivateMember);
}
However, it doesn't seem so odd for methods which require this sort of functionality. What methods require accessing a sibling's private data? Comparison methods (in particular equals) and objects in a data structure (say a tree or linked list).
Comparison methods often compare private data directly rather than just the public data.
For a class of nodes that make up a linked list, graph or tree, being able to access a sibling's private data is exactly what is needed. Code in the know (part of the class) can tinker around with the data structure, but code outside of the data structure cannot touch the internals.
It is interesting to note that these two cases are less common in day-to-day programming than when this language feature were first developed. Back in 1990s and early 2000s, in C++ it would have been much more common to build custom data structures and comparison methods. Perhaps it is a good time to reconsider private members.
i like the second point, you can look, but dont touch those private members.
it's funny you should say that, i knew a teacher once and he said he often had a problem deciding what classes it was ok to look at the members and which ones he could actually have a play with.
An object is just a piece of data; the class contains the functionality. A member method is just a nice trick the compiler plays; it's really more like a static method with an implied argument (sort of like extension methods). With that in mind, protecting objects from each other doesn't make any sense; you can only protect classes from each other. So it's natural that it works that way.
No, this is necessary, the method code is not specific to the instance, it is only specific to the type of the object. (virtual methods) or the declared type of the variable (for non-virtual methods). The non-static fields, on the other hand, are instance specific... That's where you have instance-level isolation.
The only difference between a static method and a non-static method is that the static method is not allowed to access other instance based (non-static) methods or fields. Any method that CAN be made static without modification will not be affected in any way by making it static, except to force compiler to throw errors anywhere it was called using instance-based syntax.
If you intend to examine a given student's information then I would change the method to be static:
public static void ExamineStudentsMembers(Student student)
{
Console.WriteLine(student._studentsPrivateMember);
}
You would then use Student.ExamineStudentsMembers(s1). Using s1.ExamineStudentsMembers(s2) would be invalid.
If this isn't the intended purpose I would rewrite the method as:
public void ExamineStudentsMembers()
{
Console.WriteLine(_studentsPrivateMember);
}
The above would then be used by writing s1.ExamineStudentsMembers()
Private members are to hide implementation details from clients. The clients should only see the interface (public methods / fields / properties).
The purpose is not to protect the programmer from himself.
This is also NOT a security feature because you can always access private fields via reflection.
It's really to separate interface & implementation (black box design), and clients programming against a contract (all public fields).
For example if you have a public get property, it could access some private field directly, or it could calculate the value from some other fields.
The purpose is, the client only knows the contract (the public property) and the implementation can be changed without affecting the client
Object scope does not ever imply security - ever! It is role of the OS to provide runtime security. It is a bug to design a system that relies on language specific object scope to limit runtime object instance data access. If this were not the case, then all non OO languages are, by definition, not secure.