C# Cannot Reach Class Elements - c#

It seems like a very simple error, but I could not solve it.
I have created a Class named User in User.cs, and when I instantiate it in another .cs file, it does it, but I cannot either change its properties or reach its properties.
User user = new User();
I create a new instance like this, but then I cannot reach. For example:
user.name
The content of User class is the following:
public class User
{
public static string name;
public static int age;
public static int height;
public static int weight;
}
What is the reason and how can I solve it?
Thanks

You have created a static object, don't instantiate the class to use it, just do
User.name
Alternativly remove the static keyword.
The word static means you don't need to make a new insance of the class to access something so for a class with
public Class {
public static object myAttribute;
}
Class.myAttribute
But if you don't use the static key word
public Class {
public object myAttribute;
}
Class myClass = new Class();
myClass.myAttribute;
You want to use a static value when your value does not depend on any other variables in the same class. When they do depend on varibles (or manipulations of variables) in the same class then use non static.

remove keyword static from fields

Is name public member? Set it public or create a public property to access it...
public string Name { get { return name; } }
EDIT: as name is a static member, you cannot write myUser.name. It's User.name. I think you should remove static (and learn some basis...).
What is the error message that occurs during build? It should be clear enough.

You have to declare name as public in the user class. For example:
public string name { get; set; }

You cannot access static fields from the instance of a class. You can either not declare the fields static:
public class User
{
public string name;
public int age;
public int height;
public int weight;
...
Or you can access the class statically:
User.name

Related

How to restrict access to a nested class to its container in C#?

I have a configuration class store application configuration. Currently I am using a static class. Some of the configurations are related to one topic so I want to organize them into a nested class, so I can reference configurations like this:
AppConfig.Url
AppConfig.LogSettings.FileSize
I have two options, either use a static nested class,
public static class AppConfig
{
public static class LogSettings
{
public static int FileSize {get; set;}
}
}
or declare a class but add a static property:
public static class AppConfig
{
public class LogSettings
{
public int FileSize {get; set;}
}
public static LogSettings logSettings { get; private set; }
}
However, none of them can protect nested class member FileSize being modified by other classes, even I use private set to protect the public static property.
Maybe I should not use nested class to implement this? Any suggestions?
The other solutions given so far essentially require the property being set to be set once. I am very much in favour of immutable objects, but they are not always practical; is it possible to solve your problem and make the property mutable?
This is in fact a special case of the more general problem you pose: how can we mark certain members of an inner class as being accessible only to the outer class, but not to anything outside of that class?
It is by no means obvious how to do so, but this is surprisingly easy. The key to the solution is to remember that interfaces may be private implementation details. C# requires that a base class be at least as accessible as the class deriving from it, but C# does not require that an implemented interface be as accessible as the class implementing it!
using System;
public static class Outer
{
private interface IPrivates
{
string Name { set; }
}
public readonly static Inner TheInner = new Inner();
private readonly static IPrivates TheInnerPrivates = TheInner;
public class Inner : IPrivates
{
public string Name { get; private set; }
string IPrivates.Name { set { this.Name = value; } }
}
public static void DoIt()
{
TheInnerPrivates.Name = "abc";
}
}
public class Program
{
public static void Main()
{
Outer.DoIt();
Console.WriteLine(Outer.TheInner.Name);
}
}
Code inside of Outer may access the private members of Inner via the interface. Code outside of Outer cannot see anything other than the public members of Inner, because the interface they need to see the private members is itself private.
I voted for Eric's answer but wanted to put this here as 'something to consider'.
public class Tester
{
public Tester()
{
AppConfig.LogSettings.FileSize = 5; // compile error
Console.WriteLine(AppConfig.LogSettings.FileSize); // works
}
}
public static class AppConfig
{
// just an example of setting the value in the outer class
private static void SetFileSize(int size)
{
fileSize = size; // internal only setting works
}
private static int fileSize; // a member of AppConfig still
public static class LogSettings
{
public static int FileSize
{
get { return fileSize; } // internal classes can access private members of the outer class
}
}
}
When you access AppConfig externally you get the grouping you desire, however inside the AppConfig class the 'grouping' is simply about publicly exposing the getter, the actual member variable still belongs to AppConfig.
This works because the internal class can access private members of the outer class.
So if your grouping goal is mostly about the public interface - how you get the values - this approach is simpler, but if your goal is also have the grouping internally too...then obviously it doesn't deliver.
One option is to use a constructor of nested class to initialize values. For example:
public static class AppConfig {
static AppConfig() {
Log = new LogSettings(1);
}
public class LogSettings {
public LogSettings(int fileSize) {
FileSize = fileSize;
}
public int FileSize { get; private set; }
}
public static LogSettings Log { get; private set; }
}
Then other classes can create instance of LogSettings still, but cannot modify your instance.
If this is the approach you want to go with, I see 2 options:
You extract all the logic surrounding loading and parsing of the config file into a separate project (library), than you can mark your setters internal and other libraries won't be able to access them anymore.
You can implement a more explicit property which doesn't allow to set a value twice like:
private int? _fileSize;
public int FileSize {
get { return _fileSize ?? 0; }
set {
if (_fileSize.HasValue) {
throw new InvalidOperationException("You can only set the value once");
}
_fileSize = value;
}
}
Another option, which I've often used, is to encapsulate the parsing of different parts of a configuration to the sub classes. You provide that information in the constructor and the class initializes itself. (just like Evk commented in the meanwhile)

from / where Can i call static class methods in a class?

I have the below code in the same namespace.
public static class usercls
{
public static int testc()
{
int s=1;
}
}
public class User : Page
{
private static User user;
int s=usercls.testc();//why not accessible here?
}
I'm unable to access the static class outside of the class. Can someone help me to identify this?
Hi the function testc() doesnt return any value.
It should look like this
public static int testc()
{
int s=1;
return s;
}
or like this
public static int testc()
{
return 1;
}
After that your code should compile.
Other classes cannot access the class functions of usercls because the compiler did not compiled it, because there was an error, once you fix that error, it will be accessible from all the other classes.
Also
You are trying to call it directly in your other class, the call should be within a function like so:
public class User : Page
{
private static User user;
public User()
{
int s=usercls.testc();//why not accessible here?
}
}

Set newly created object equal to another instance in overloaded constructor

Can I set the newly created object equal to the supplied object in the constructor of the class?
I want to do something like this:
public MyClass
{
public MyClass(MyClassDto myClassDto)
{
MyClass convertedMyClassObj = AutoMapper.LoadEntityFromDto<MyProject.DTO.MyClassDto, MyClass>(myClassDto);
//Assign the new object being created here equal to convertedMyClassObj:
this = convertedMyClassObj; //I want to reference the current object in place of 'this'.
}
public int MyProperty1 { get; set;}
public int MyProperty2 { get; set;}
public int MyProperty3 { get; set;}
}
I don't want to do it property by property. Do I have to use a a singleton like procedure to return the copied instance in a GetInstance() method. Because constructor has no return parameter. I just want to know if this is possible or not.
You won't be able to do that because this can't be set. But you are already using AutoMapper which creates your object from your DTO. You could just use a static method if you want a shorthand.
public MyClass
{
public static MyClass FromDto(MyClassDto myClassDto)
{
return AutoMapper.LoadEntityFromDto<MyProject.DTO.MyClassDto, MyClass>(myClassDto);
}
//Properties
}
Then you would just use it with
var myClass = MyClass.FromDto(myClassDto);
There is an overload of AutoMapper.Map that takes a reference to an existing destination object.
public static TDestination Map<TSource, TDestination>(TSource source, TDestination destination);
You can use it with this to set the properties based on the DTO:
class MyClass
{
public MyClass(MyClassDTO dto)
{
AutoMapper.Mapper.Map(dto, this);
}
}
The problem with this approach is that MyClass gets coupled to Automapper and MyClassDTO. It might be better to move the responsibility of converting MyClassDTO to MyClass to a separate class.
You're essentially talking about creating a factory, and if you look at the factory pattern, the key is a static class that does the work of instantiating the new "thing". So, no, you can't really do this like you're trying to, but if you want to encapsulate the AutoMapper logic, then you can simply do something like:
public static class MyClassFactory
{
public static MyClass FromMyClassDto(MyClassDto myClassDto)
{
return AutoMapper.LoadEntityFromDto<MyProject.DTO.MyClassDto, MyClass>(myClassDto);
}
}
Then:
var myClassInstance = MyClassFactory.FromMyClassDto(myClassDto);
You cannot assign a value to this in a class. You'll need to copy the values over.

This way of using struct puzzled me

As I know before using a struct , I must have a object of it. Then I can't understand the following codes. Maybe the problem is somewhere else I can't find. Please help me.
namespace Ixxat.Vci3.Bal.Can
{
public struct CanBitrate
{
.....
public static CanBitrate Cia10KBit { get; }
public static CanBitrate Cia125KBit { get; }
public static CanBitrate Cia20KBit { get; }
public static CanBitrate Cia250KBit { get; }
public static CanBitrate Cia500KBit { get; }
public static CanBitrate Cia50KBit { get; }
public static CanBitrate Cia800KBit { get; }
// Gets an array of all available CiA baud rates.
public static CanBitrate[] CiaBitRates { get; }
// Gets a empty bit timing value.
public static CanBitrate Empty { get; }
public string Name { get; }
public override sealed string ToString();
}
}
Abrove all is the given interface, I think the "Cia125KBit" is a function of the struct. Then in another file, there is a function like this:
mCanCtl.InitLine( CanOperatingModes.Standard | CanOperatingModes.ErrFrame
, CanBitrate.Cia125KBit);
the definition of the InitLine is as follows:
public interface ICanControl : ICanSocket
{
...
void InitLine(CanOperatingModes operatingMode, CanBitrate bitrate);
}
My question is , CanBitrate is the name of struct, why it can be used in the function like CanBitrate.Cia125KBit? As I learned, It should like this
CanBitrate a;
a.Can125KBit;
I think there must something I am unknown or misunderstand . Ask for help.
Cia125KBit is a static member which means that it can be accessed without creating an instance of the struct. As MSDN puts it,
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.
To contrast this, the member Name is not declared as static. Therefore, trying to do something like CanBitRate.Name would throw an error.
The thing you're missing is the keyword static. A method, property or field of a class can be declared static to decouple it from individual instances, meaning that it's accessed through the class itself as opposed to objects.
It's because Cia125KBit is a static member. Static members are not bound to any instance and can be accessed only via class/struct name.

C# new class clears base class values

I've searched extensively (though might have missed it). I've been doing so much web development that I can't seem to get this. I have a base case:
public class myfields
{
public String myfield1 { get; set; }
}
Then another class using this class:
class mydohere : myfields
{
public Boolean getValue {string xyz)
{
string abc = myfield1;
}
}
What I can't get it is, if I create:
mydohere Objmydohere = new mydohere();
The value of myfield1 is now null! All the values in base myfields are set to null (or empty since it is a new object). What is the best way to create fields (or parameters) in one class and share it among others without resetting their values? I've tried using keyword 'base'. I've tried using props and fields *since you can't instantiate them).
My goal is to to have a class of settable fields that I can use accross classes without making that class new for each class that is using it. Does this make sense? I'm sure there is a much better way to do this :)
It sounds like what you're looking for is a constant or static variable.
Use constant if it will always be the same:
const string myfield1 = "my const";
Use static if you'd like to set it once, maybe after doing some logic:
static string myfield1 = "my static";
This really depends on what you want to do with this "shared data" One way is to use a static class and dependency injection:
public interface Imyfields
{
String myfield1 { get; set; }
}
public class myfields : Imyfields
{
private static readonly Imyfields instance = new myfields();
private myfields()
{
}
public static Imyfields Instance
{
get
{
return instance;
}
}
public String myfield1 { get; set; }
}
class mydohere
{
private readonly Imyfields myfields;
public mydohere(Imyfields myfields)
{
this.myfields = myfields;
}
public Boolean getValue(string xyz)
{
string abc = this.myfields.myfield1;
}
}
Nothing is reset to null, it's never initialized with a value in the first time. In your base object, you only have a getter/setter, you don't have any code that initialize the value itself.
Maybe I don't understand the question well and others suggestion with static are what you really need! :)

Categories

Resources