Cannot access nested classes or members of base class - c#

I'm having some weird problems here with a Class that I've written. I cannot access anything inside of Account, unless I access it directly from Account.Whatever.
I'd like to be able to do:
Account account = new Account();
account.Name...
but I can't. Nothing shows up in intellisense. I can only access things if I do:
Account. - for example, Account.AccountHolder...
class Account
{
class AccountHolder
{
enum Salutation
{
Mr,
Mrs,
Ms,
Miss,
Dr,
Hon
}
struct Name
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
enum Sex
{
Male,
Female
}
}
}
I don't understand what's going on. Note, that I have also tried every possible combination of things but something is very wrong here. I've tried adding public to my Account class. I've tried adding public to my AccountHolder class. I've tried using public static etc etc etc.
I've never had this problem before. And why am I experiencing this same problem no matter how much I change it around?
The Account class is in an Account.cs file inside the same winforms project.

One real question might be: Why do you need Nested Types here at all?
Nested types are especially used when no other types cannot reuse a type of your parent type, that is, if your nested type shall expose properties or values only applicable to your parent type. Otherwise it is mostly best to create independant types.
To me, it looks reasonable to think that you might use the Salutation enumeration outside of the AccountHolder class, as an Account Holder is nothing more than a legal entity, that is, a real person or a company.
If your system could use Salutation elsewhere, than it is best to create the enumeration per itself, in its own file, and expose a property out of your AccountHolder class.
Salutation
public enum Salutation {
Mr
, Mrs
, Ms
, Miss
, Dr
, Hon
}
AccountHolder
public class AccountHolder {
public Salutation Salutation { get; set; }
// ...
}
In the later, one might also be insterested to know what's an account holder at once?
Might it be a company, a person, a customer, a supplier, or else?
Then perhaps shall you consider to define a hierarchy of account holders and make it a property of the most general class type.
LegalEntity
public class LegalEntity {
public string Name { get; set; }
}
Company
public class Company : LegalEntity {
// Some members specific to a Company here...
}
Person
public class Person : LegalEntity {
public Salutation Salutation { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get { return base.Name; } set { base.Name = value; } }
// Some other members specific to a person here...
}
Then, you have your Account class
public class Account {
public LegalEntity AccountHolder { get; set; }
}
So my point is that there is no use of Nested Types here, depending on your needs, which I'm not actually aware, obviously. And it turns out that an AccountHolder may now be of any types deriving from LegalEntity. Later on, when there is a need for another type of AccountHolder, you may simply derive from LegalEntity, or any other types which actually derives from it to make it an AccountHolder, as an AccountHolder is simply a property of an Account, and not a class per itself.
Some examples of using Nested Types adequately:
Why Would I Ever Need to Use C# Nested Classes
Why/when should you use nested classes in .net? Or shouldn't you?
Furthermore, you will need to make your Nested Types public in order to access them from outside of your class. This doesn't mean that will be able to avoid the Parent.NestedType nomenclature, you will not.
Apart from it, I see no problem in your code. Nested Types are by definition hidden somehow within another type. So when you wish to access them, you always need to type in the parent name which contains the type you need to access.
Plus, once you can access the Nested Type, you will be obliged to create members into your Account class to holde references to your instances of those Nested Types. IMHO, there is no gain of using them here. But hey, I insist, I'm not aware of your reality and the choices behind your design.

You are trying to access nested class, struct, enum. It should be done with the nesting class name, e.g. Account.Name.
But if you have
class Account
{
public struct Name
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public Name MyName {get; set;}
}
then you may access the MyName property using the instance of Account class.

This is how the language works.
What you are probably wanting to use here are namespaces. Any nested class will always have to be fully qualified with its parent classes to be used. If you use a namespace, anything within that namespace can be used together without fully-qualifying, and can be used outside the namespace (within the bounds of access modifiers) by either fully-qualifying or by inserting a using directive (using Accounting; in this case).
Also, are you sure you want to be using a struct? Value types are immutable, so if you change any member of that struct, you're always creating an entirely new instance of the struct (generally significantly less efficient).
namespace Accounting
{
class Account
{
public PersonName Name { get; set; }
public Sexes Sex { get; set; }
public Salutations Salutation { get; set; }
}
class PersonName
{
public string First { get;set; }
public string Middle { get; set; }
public string Last { get; set; }
}
enum Salutations : byte
{
Mr,
Mrs,
Ms,
Miss,
Dr,
Hon
}
enum Sexes : byte
{
Male,
Female
}
}

Related

Is sharing base and derived class names a bad practice?

Since people have requested more context, I will try to provide a concrete example of the problem. I am doing some sort of generic ERP system that displays the usage of resources in a diagram. I have some generic classes that are used to model the problem such as Job, Resource, and Operation. Something like this:
public class Job
{
public string ID { get; }
public string Name { get; set; }
public DateTime Arrival { get; }
public Job(string id, DateTime arrival)
{
Arrival = arrival;
ID = id;
}
}
public class Resource
{
public string ID { get; set; }
public string Name { get; set; }
protected Resource(Resource other) => ID = other.ID;
}
public class Operation
{
public string ID { get; }
public string Name { get; set; }
public Job ProcessedJob { get; }
public Resource Processing Resource { get; }
public Operation(string id, Job processedJob, Resource processingResource)
{
ID = id;
ProcessedJob = processedJob;
ProcessingResource = processingResource
}
}
However, the application is generic so this modeling may not be enough for all possible problems. For example, there may be Jobs that have properties such as the maximum time they can take to be processed or resources that have a certain schedule. The thing is that depending on the concrete problem I am modeling these characteristics may be part of the problem or not so expanding each class whenever a new problem case arises doesn't seem a good idea since it will pollute the code.
The obvious solution is inheriting from each base class and having a derived class for each problem case so that includes the desired properties, such as Problem1Job and Problem1Resource. In my opinion, this also gets messy if more problem cases or base classes are added because the total file count increases. An example of this could be (I didn't include constructors for the sake of clarity):
public class Problem1Job : Job
{
public bool ExtraPropertyA {get ; set; }
public string ExtraPropertyB {get ; set; }
public int ExtraPropertyC {get ; set; }
}
public class Problem1Resource : Resource
{
public bool ExtraPropertyA {get ; set; }
public int ExtraPropertyB {get ; set; }
}
Instead of storing all these classes in one folder, I have decided to group all the base classes in one folder called base, with its own namespace, and create a folder for each of the problems with a different namespace. This allows me to create classes that are Job : base.Job and Resource : base.Resource inside the namespace Problem1, thus sharing the name with their base classes but in a different namespace. For me, it is a clean way to organize the files, but I don't know if there is any convention regarding sharing the names between the base and derived classes (given they are in different namespaces) or if it is considered a bad practice/code smell.

C# Get value of a property from an object hidden behind Interface

To explain it better, I have an object that has property of interface type that can be carrying a variety of different objects.
public class RequestParameters {
public IRequest Request { get; set; }
}
Say the interface looks something like this:
public interface IRequest {
string Username { get; set; }
string Password { get; set; }
}
Now upon receiving the RequestParameters object, I want to get the value of a property PersonId from the object inside Request property. The interface doesn't and shouldn't contain this property, as not all of the Request types have that property. And I don't know which of the dozens of types will the Request object correspond to, so casting isn't a solution.
So how can I possibly fetch the property PersonId in such a case? I suppose some sort of reflection is the only way, but how exactly can it be done?
What about creating an intermediate interface?
public class RequestParameters
{
public IRequest Request { get; set; }
}
public interface IRequest {
string Username { get; set; }
string Password { get; set; }
}
public interface IRequestWithId : IRequest
{
string ID {get; set; }
}
Now you can check against that interface instead of a concrete class to check if there is an ID or not.
Other than that there is only reflection which is a really bad idea here. When defining interfaces you want to reduce code-coupling which means you donĀ“t want to rely on actual types (that define how things are done) but only their behaviour (what can be done with them). Using reflection would circumvent this as you indirectly rely on the actual types. Furthermore using reflection is bad for maintainance, in particular when you refactor the methods (renaming for example).
first of all, in c# there is another type called abstract class which in my opinion would be a better suit for your situation. take a look at this question. interfaces are not meant to hold variables, only functions.
public abstract class ARequest
{
string Username { get; set; }
string Password { get; set; }
public abstract int GetId() {}
}

using a class name in another class property.? [duplicate]

This question already has answers here:
virtual properties
(7 answers)
Closed 7 years ago.
I am pretty new to C#. I have two classes a Movie class and a Genre class.I cant understand the property "public virtual Genre Genre" Could someone explain me this? Following are the two classes
public class Genre :IEntityBase
{
public Genre()
{
Movies = new List<Movie>();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Movie> Movies { get; set; }
}
public class Movie:IEntityBase
{
public Movie()
{
Stocks = new List<Stock>();
}
public int ID { get; set; }
**public virtual Genre Genre { get; set; }**
public virtual ICollection<Stock> Stocks { get; set; }
}
public virtual Genre Genre { get; set; } means the following:
Declare a property named Genre (the second occurrence)
This property is of type Genre (the first occurrence)
This property can be read (get) and can be changed (set).
This property can be read or set by any other class in any other library that has access to this object (public)
This property can be overridden (have it's code replaced to do something different) by a subclass. (virtual).
The type and the name are Gender which to you might look confusing but for the computer it's like this:
a bunch of modifiers like public, private etc. + the type + the name
So it actually doesn't consider the second Gender as a type because it's just a name for something. Under the hood, it's not referring to the variable/properties you create by their name anyway. It uses some kind of pointer or reference.
Now, if you mean to ask how to interpret that particular definition, it says that the property is supposed to be seen outside the class (it's not hidden/private). It's also possible to alter its meaning if you use inheritance. It will return something of type Gender (the class) and it's name is Gender (and it could be called almost anything, if you wish). I t also says that it will work as a container for that Gender-like value and you can freely assign it and read it.
Most of the details are of importance and can be seen to modify the behavior when you start using the instances of it in a bigger scope. Just in this example, it's really no difference if you go public or virtual. Did it help?

Can a Custom C# object contain a property of the same type as itself?

If I have created the following Employee object (simplified)...
public class Employee
{
public Employee()
{
}
public String StaffID { get; set; }
public String Forename { get; set; }
public String Surname { get; set; }
}
... would it be acceptable to have another property in the Employee object with a Type also being Employee to hold their Manager's details (as shown below)?
public class Employee
{
public Employee()
{
}
public String StaffID { get; set; }
public String Forename { get; set; }
public String Surname { get; set; }
public Employee Manager { get; set; }
}
Also, what is the best way to instantiate the Employee object for the Manager property? Obviously including this.Manager = new Employee(); in the constructor will cause an infinite loop. Would a Manager class that inherrits from Employee be the best way (even though all the properties would be identical)?
An object can indeed have a reference to an object of its own type.
This is how most Node type objects are implemented.
As for instantiation - you can pass in the Employee object to use as manager (passing in null for no manager). Constructors can have multiple overloads:
public Employee(Employee manager)
{
this.Manager = manager;
}
Yes, an object can contain references to other objects of the same class.
And secondly, I wouldn't create a new Employee in the cunstructor but inject it like this:
public class Employee
{
public Employee(Employee manager)
{
this.Manager = manager;
}
public String StaffID { get; set; }
public String Forename { get; set; }
public String Surname { get; set; }
public Employee Manager { get; set; }
}
The only scenario where this isn't possible is with a struct; a struct is contained directly (rather than being a fixed-size reference to the data), so the size of an Employee struct would have to be "the size of the other fields plus the size of an Employee", which is circular.
In particular you can't have:
struct Foo {
Foo foo;
}
(or anything else that would result in a circular size) - the compiler responds with:
Struct member 'Foo.foo' of type 'Foo' causes a cycle in the struct layout
However, in all other cases it is fine; with the issue of initialisation, I'd say: just leave it unassigned initially, and let the caller assign a value via the property.
First, the answer is Yes an object can have a field that contains an instance of itself. It can even have methods that accept or return the instances of the same class, and it can even depend on itself in the definition of the class, e.g:
public class Person : IComparable<Person> //legal, recursive definition
{
//fields (or properties) that are of type Person
public Person Father;
public Person Mother;
public List<Person> Children;
// method that takes a Person as a parameter
public bool IsParent(Person potentialParent)
{
....
}
//method that returs a Person
public Person Clone()
{
//TODO: real implementation coming soon
}
public Person(){}
//constructor that takes persons as arguments
public Person(Person father, Person Mother)
{
Father = father;
Mother = mother;
}
}
By default all reference values are null'd so you won't have a constructor problem unless you create one yourself. So, Yes, there can be some issues with circular references and endless loops (each parent has children that have children that have parents etc...) but usually they can be trivially detected and avoided.
The only times I've encountered these kind of problems is when I used XML (or other text-based) serialization on circularly referenced objects.
Yes, you can have Employee inside Employee and it will not cause infinite loop, by default Manager property of Employee object will be null.
It works, you can just try s.th. like:
public class A
{
public A test { get; set; }
}
Specifically on the issue of construction (I've +1'd Odeds answer) - as you say constructing an instance in the constructor is a bad move.
But then ask yourself - why would you ever need to anyway. In your Manager/Employee case - you can't always be sure that an employee always has a manager, and if they don't then you shouldn't be using a newed empty instance to signify that, but a null.
When your type will have public get/set accessors on the properties, generally you're likely to be loading these object trees from some external source, in which case you have nothing to worry about. Equally, you can have a constructor that accepts other Employee instances for Manager/Employee relationships etc.
You should also be checking for circular relationships in that constructor as well - i.e. an employee can't be someone's manager and their employee - try walking the child->parent relationship for that and see if it ever ends!
I tried this way and it worked for me:
class Program
{
static void Main(string[] args)
{
A a = new A(new A());
}
}
public class A
{
public string Name { get; set; }
public A a;
public A() { }
public A(A _a)
{
a = _a;
}
}
Now you can use it in the Main() function like:
class Program
{
static void Main(string[] args)
{
A a = new A(new A());
a.Name = "Roger";
a.a.Name = "John";
Console.WriteLine("{0}, {1}", a.Name, a.a.Name);
}
}

Aggregation versus Inheritence in C#, or alternatives

Let's say I have the following two classes:
public class Person
{
public string Name { get; set; }
public string Address { get; set; }
}
public class Customer: Person
{
public string CustomerNumber { get; set; }
public string PaymentTerms { get; set; }
}
Now, if I have a person that I want to make a customer, I have, to the best of my knowledge, three options, and I'm hoping for advice on which is the best and on any other options, maybe using the new dynamics stuff in C#4.
I can add a constructor or property to Customer that takes a Person and assigns values to the base class, e.g.
public Customer(Person person)
{
base.Name = person.Name;
base.Address = person.Address;
}
or I can implement an untidy set accessor like this:
public Person Person
{
set
{
Name = value.Name;
Address = value.Address;
}
}
or I can aggregate Person into Customer like this:
public class Customer
{
public Person Person { get; set; }
public string CustomerNumber { get; set; }
public string PaymentTerms { get; set; }
}
The last is to me the neatest, except for always having to e.g. access Customer.Person.Name, instead of just Customer.Name.
I would personally go for composition, yes (your last option). Note that you can always provide "helper properties":
public string Name { get { return Person.Name; } }
Indeed, you can do this for all the properties you want, and never expose the Person property to the outside world at all.
On the other hand, inheritance is useful if you want to be able to treat a Customer as a Person - passing it to methods with a Person parameter, for example. I usually accomplish that sort of thing with interfaces though; you could have an IPerson interface implemented by both Customer and Person. Inheritance introduces all sorts of design decisions which simply don't come up (or are a lot simpler) when you don't get into inheritance.
I'd either use the constructor, or maybe a factory method, like
public static Customer CreateFromPerson(Person person)
{
return new Customer(){ Name = person.Name }//etc...
}
I don't like the setter as you're not actually setting the 'Person' on a customer, and I don't like the last option because it leads to a Law of Demeter (LOD) violation when you access the person through the customer (customer.person.name etc).

Categories

Resources