accessing objects from a class - c#

I have created a seperate .cs file names aNameClass.cs and have stored the following class in it.
I am able to iniatiate it in my Main() statment, but when I try to access the GetChoice object, it tells me it is inaccesable due to invalid prividlidges.
here is my code to iniatiate it and access it.
namespace aNameCollector
{
// ...
csGetChoice gc = new csGetChoice();
choice = gc.GetChoice(); //invalid prividlidges???
class csGetChoice
{
static string GetChoice()
{
string choice = " ";
Console.WriteLine("++++++++++++++++++=A Name Collector+++++++++++++++");
Console.WriteLine();
Console.WriteLine("What would you like to do?");
Console.WriteLine("E = Enter a Name || D = Delete a Name || C = Clear Collector || V = View Collector || Q = Quit");
choice = Console.ReadLine();
return choice;
}
}

You need to use a static reference and specify public for the method like this:
// static access:
choice = csGetChoice.GetChoice();
...
public static string GetChoice() { ...
or make the method an instance method instead of static and define and access it like this:
// instance access:
csGetChoice gc = new csGetChoice();
choice = gc.GetChoice();
...
public string GetChoice() { ... // static keyword removed
If you don't provide an access modifier the default is private and therefore visible only to the class that contains it and not to any other classes.

Make the method public and call the static method on type not on the instance
csGetChoice.GetChoice();

The static key word for a type member states that you can access it by referencing the class directly and not its objects. However, you still need the right access modifier to be able to access that member.
private is the default value when you don't explicitly declare the access modifier in C# as in your case. And that allows you to access that member only inside its class.
To be able to access it from outside the class you need to explicitly use other access modifiers as public.

Related

I can't get value of base class field from child class object in c#

using System;
public class Program
{
public static void Main()
{
CloudCollectionHelper cloudHelper = new CloudCollectionHelper();
SlackHelper slackHelper = new SlackHelper();
cloudHelper.DatabaseID=12345;
Console.WriteLine(slackHelper.GetSlackPageTokens());
}
class CloudCollectionHelper
{
public long DatabaseID { get; set; }
}
class SlackHelper:CloudCollectionHelper
{
public long GetSlackPageTokens()
{
return DatabaseID;
}
}
}
current output: 0
Expected Output: 12345
I need output 12345 because DatabaseID from the cloudhelper so i need that databaseID in the slackhelper.
this is my c# online compiler: https://dotnetfiddle.net/QNQeEX
The child class does not get the assigned values from the base class. Becouse there can be mutliple instances from it. For example, if you have
...
CloudCollectionHelper cloudHelper1 = new CloudCollectionHelper();
CloudCollectionHelper cloudHelper2 = new CloudCollectionHelper();
cloudHelper1.DatabaseID = 1234;
cloudHelper2.DatabaseID = 6789;
Console.WriteLine(slackHelper.GetSlackPageTokens()); //It would not know, what value to use.
...
The best way would be assigning the value directly to the child class or using the static modifier.
Edit:
Best way if you need to take this value from the child class for whatever reason would be doing something like this:
...
CloudCollectionHelper cloudHelper = new CloudCollectionHelper();
cloudHelper.DatabaseID = 12345; //First assign the needed Value
SlackHelper slackHelper = new SlackHelper(cloudHelper); //then create a new instance from the child class
...
and add the constructor from the SlackHelper child class like this:
class SlackHelper:CloudCollectionHelper
{
public SlackHelper(CloudCollectionHelper cloudHelper)
{
this.DatabaseID = cloudHelper.DatabaseID;
}
... //Do everything else what this class needs here
}
If the Value from cloudHelper.DatabaseID can update during the runtime, you will need a event to update the child class. It still isn't the best way to do this, because the DatabaseID value is already public and can be accessed without the child class.
Edit 2:
Like I already told you in the comments, you could also avoid this problem with the static modifier. But this will effect every instance made from the CloudCollectionHelper class. As soons as you make it static, this will only hold 1 possible value for all instances.
(Please keep in your mind to use a comment if needed or best case, just avoid Magic numbers)
The property of your Object slackhelper has not been affected.
You don't need to create a CloudCollectionHelper Object.
SlackHelper slackHelper = new SlackHelper();
slackHelper.DatabaseID=12345;
Console.WriteLine(slackHelper.GetSlackPageTokens());
You should create this property inside the class to allow to read the Database ID
public long GetSlackPageTokens()
{
return base.DatabaseID;
}

Wrapping a Generic class inside a non Generic class C#

I'm working on a C# console application. My objective is to create an object called GroupEntity, preferably of non generic type.
Inside this GroupEntity object will be a List of 'AttributeFilter' object which contains object of Generic type which hold the attribute name on a user object in Active Directory and the possible values of those user objects. The reason I want the AttributeFilter object to take a generic type is because some attributes on user objects in AD are string, some are int32, some are int64 etc.
Here are my classes (I've cut out the contructorse etc to save space here)
public class AttributeFilter<T> : IEqualityComparer<AttributeFilter<T>>
{
private string _attributeName;
private T _attributeValue;
private List<T> _attributeValues { get; set; }
public AttributeFilter(string attributeName)
{
AttributeName = attributeName;
_attributeValues = new List<T>();
}
public void AddValues(T attributeValue)
{
AttributeValue = attributeValue;
if (!_attributeValues.Contains(AttributeValue))
{
_attributeValues.Add(AttributeValue);
}
}
// Ive cut out the getter setter etc that is not relevant
}
Here is the GroupEntity class. Notice I have a
List<AttributeFilter<T>>
field. Problem is I dont know what that T will be until I run program.cs
public class GroupEntity<T>
{
private string _groupName;
// because I want to a have a List<AttributeFilter<T>>, but I dont really want this here. because of program.cs when I initialise a new GroupEntity<> I have to tell it what type. I wont know. The type could be int32, string, long or whatever.
private List<AttributeFilter<T>> _filters;
public void AddFilters(AttributeFilter<T> attributeFilter)
{
if (!_filters.Contains(attributeFilter, attributeFilter))
{
_filters.Add(attributeFilter);
}
}
public GroupEntity()
{
_filters = new List<AttributeFilter<T>>();
}
public GroupEntity(string groupName) : this()
{
_groupName = groupName;
}
}
Now I use program.cs to initialise and test...
class Program
{
static void Main(string[] args)
{
// Create AttributeFilter object for user attribute: EYAccountType
var at1 = new AttributeFilter<string>("EYAccountType");
at1.AddValues("02");
at1.AddValues("03");
at1.AddValues("04");
at1.AddValues("05");
// try adding anothr AtributeFilter with same name.
var at3 = new AttributeFilter<string>("EYAccountType1");
at3.AddValues("06");
at3.AddValues("07");
// Create AttributeFilter object for user attribute: userAccountControl
var at2 = new AttributeFilter<int>("userAccountControl");
at2.AddValues(512);
at2.AddValues(544);
at2.AddValues(546);
at2.AddValues(4096);
// Now create a GroupEntity object
var group1 = new GroupEntity<string>("My_First_AD_Group_Name");
// Try adding the above two AttributeFilter objects we created to the GroupEntity object.
group1.AddFilters(at1);
group1.AddFilters(at3);
// This is the problem. I know why this is happening. because I initialised the var group1 = new GroupEntity<string>. So it wont accept at2 because at2 is taking in int.
//group1.AddFilters(at2);
}
So how can I write my GroupEntity class without a generic parameter so I can hold various types of AttributeFilter<T> inside it. So for example, I can hold AttributeFilter<int> and AttributeFilter<string> and AttributeFilter<long>
I can't seem to figure out this problem.
More or less you can't.
Generic types instantiated with different types has no relationship to each other (i.e. AttributeFilter<long> and AttributeFilter<int> don't get any common base class - they are as differnet as Exception and HttpClient). So there is no way to put instances of such types into single collection with strong typing.
Standard solution - use non-generic base class or interface for your AttributeFilter<T> type. Alternatively - store them as collection of object and lose all type safety, or maybe collection dynamic which at least give you chance to call methods (at cost of reflection).

Dot notation for class member access

I've got the following code:
public class Random
{
public string Name { get; set; }
public bool IsRunning()
{
var running = true;
return running;
}
}
public class Main
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
which all exists in the same .cs file in the same namespace. Any time I've created a new project before I've never had to set up anything to use dot notation to access member attributes or methods, but this is saying that I can't use newObject. ANYTHING, and also that "var" is not valid for a keyword. It's a windows forms application like I normally use, but I'm drawing blanks here as why I can't do all these things that I normally use many times in my other programs. What am I missing here?
You're trying to write code directly within the class declaration. A class declaration can only directly contain member declarations. It can't contain arbitrary statements such as newObject.Name = "Johnny" nor can it use var, which is only applicable to local variables. If you put the code in a method, it should be absolutely fine. For example:
public class Main
{
public void DoSomething()
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
}
As an aside, I'd strongly recommend against naming your own class Random given that that's also the name of a class within the System namespace.
You cannot use var or assign values to some other object within a class member definition.
You code in public class Main is not within a method.
I guess what you were trying to do is writing a Console app and that needs a
public static void Main()
method
so change your class to e.g.
class Program
{
static void Main(string[] args)
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
}

How to use Application.Current.Properties or some other Global variable

I have a class called RandomGen which generates random variables when called like so:
RandomGen u = new RandomGen();
int QRNOne = u.QuestionRandNo(n);
n++;
How do I then set QRNOne as a global variable to be accessed later? Also, can I do this from within the class, and have it create this variable? (I realise there is no "real" global variable in C# WPF, but you ought to understand what I'm referring to.)
Please read up on static class members.
I'm sure you know that global variables are best avoided if possible, but if you really need a static member variable then you would do something like this:
public class MyClass
{
public static int QRNOne {get; private set;}
public void GenerateRandom(){ ... ; QRNOne = ...; }
}
And then refer to that variable from elsewhere as
public void SomeOtherMethod()
{
int qr = MyClass.QRNone;
...
}
Can you use a static, Singleton style class with properties tor the values you want to use? This should then have global visibilty with sufficient structure and encapsulation.

C# accesing non static member in a static function

So I have a function:
List<string> names = new string();
private static void getName(string name)
{
names.add(name);
}
When I attempt to compile I get a:
'object reference is required for the non-static field' notice.
What do I have to do to make this member (names) compatible with getName?
I need it to be non static or converted because I want to put the results into other non static functions and forms.
You need to tell the system which list of names you're interested in. It's part of the state of an object, an instance of the class... but which one? Maybe you've created several instances of the class - maybe you've created no instances of the class. The static method has no visibility of that - so which instance do you want it to fetch the names variable value from?
To put it in another example, suppose we had a class like this:
public class Person
{
public double MassInGrams { get; set; }
public double HeightInMetres { get; set; }
public static double ComputeBodyMassIndex()
{
// Which person are we interested in?
}
}
Person p1 = new Person { MassInGrams = 76203, HeightInMetres = 1.8 };
Person p2 = new Person { MassInGrams = 65000, HeightInMetres = 1.7 };
double bmi = Person.ComputeBodyMassIndex();
What would you expect the result to be? You've asked the Person class to compute "the BMI" but without telling it whose BMI to compute. You need to give it that information.
Some options for your situation:
Change names to be static instead
Change the method to be an instance method
Pass in an instance of the class
Create an instance of the class, possibly returning it
Fetch an instance of the class some other way
By the way, that's a very strange method name for something which adds a name. It's also somewhat unconventional...
You need to make names static if you want to use it from inside of a static method:
// If this is static, you can use it from your static method
static List<string> names = new List<string>();
The issue is that getName is defined on your type, not on an instance of the type. However, names is defined so each instance of your type gets its own value.
names is an object that will exist in the instances of the class e.g. MyClass mc = new MyClass(); then you can access mc.names. A static field can be called without an instance of the class just with the classname, e.g. MyClass.getName(""); will work. So when you think logically, the class doesn't contain names, only 'the instances of that class' contain it. Therefore, you either make that list static too and it will be 'the same List instance' everywhere when you call MyClass.names or make the getName method non-static, and it will be only called from instances, therefore no MyClass.getName("") will be possible, but mc.getName(""); It's a matter of what you are exactly trying to do.
Static methods can not access class fields. Either make names static, or make getName() non-static. What do you mean by "Compatible". Ask yourself... does the method need to be static? What is its purpose and how do you intend to use it?
You cant access it this way, you need to instanciate the class containing a member.

Categories

Resources