Property access restriction in C# - c#

Trying to get the reason behind it.
Scenario#1
public class Customer
{
string _name = "Ram";
//now trying to assign some new value to _name on the next line
_name // this property is inaccessible on this line.
}
Scenario#2
public class BaseCustomer
{
protected string _name;
}
public class DerivedCustomer : BaseCustomer
{
_name //inaccessible here
public void SetName()
{
_name = "Shyam"; //accessible here
}
}
Can somebody please let me know what is cause behind this??

Simple. You can't make variable assignments (without declaration) in the class context. You need to use a constructor to put the assignment in:
public class DerivedCustomer : BaseCustomer
{
public DerivedCustomer()
{
_name = "hello";
}
...
}
... or put it in the declaration:
public class BaseCustomer
{
protected string _name = "hello";
}

Note: Experts will probably find exceptions to my simplified explanation. I'm keeping it simple for the sake of explaining the key intention to OP.
In a way, a class really only contains declarations. This can be a field:
public class Customer
{
private string _name;
}
Or a property:
//Example 1 - Simple property
public class Customer
{
public string Name { get; set; }
}
//Example 2 - Publically gettable (but not settable) property with private field (which is settable)
public class Customer
{
private string _name; //this is a field
public string Name => _name; //this is a property that relies on the field
}
Or a method:
public class Customer
{
public string GetName()
{
return "John";
}
}
Boiling it down, I would summarize it as follows:
A class only contains declarations of how it is structured: fields, properties, methods.
A class does not directly contain code (i.e. logic which uses the fields/properties).
However, a class' method or property can contain code (i.e. logic which uses the fields/properties), but this code is considered to be part of the method/property, not part of the class (directly).
What you're trying to do doesn't quite make sense to me. I'm not quite sure what you're hoping to achieve by trying to access the _name in those locations.
It only makes sense to reference this field in the locations where you can reference it:
In a method body - If you need the field during the method's execution
In a property - When the field is used during the set/get of a property
In a constructor - To set the value of the field.
But you're trying to put in in the class. This raises many questions:
What are you trying to do with _name?
Assuming you could reference the field where you want to; when are you expecting this code to be executed?
How would this be any different from simply using a method (or the constructor)?

Related

Setting constants/enums at run-time?

This seems like an odd request, I appreciate that, but this is the situation:
I have a program which depends on reading in a handful of files. These files are named like: foo_bar_BAZ.txt where BAZ is the name of the project and not known until run-time. However it will not change for the entire execution of the program.
I want to have an enumerated list of strings which stores all the filenames. So far I have used a sealed class like so:
public sealed class SQLFile
{
private readonly String name;
private readonly String value;
public static readonly SQLFile CrByAuthors = new SQLFile("Changes_CR_By_Authors_%project_name%.txt", "CrByAuthors");
public static readonly SQLFile DocumentCrMetrics = new SQLFile("Changes_Document_CR_Output_%project_name%.txt", "DocumentCrMetrics");
[...]
private SQLFile(String value, String name)
{
this.name = name;
this.value = value;
}
public String ToString(string projectName)
{
return this.value.Replace("%project_name%", projectName);
}
}
As you can see this depends on my providing the project name variable every time I want to access the filename, even though that filename is really constant from the very beginning of run-time till the end.
Is there a more elegant way to handle with this situation?
A simple solution would be to have a static class with a ProjectName property. The value of this property is set during startup of the application. Your class then can use that property.
Add a static property to SQLFile, something like
public sealed class SQLFile
{
//...
private static string sProjectName;
public static string ProjectName
{
get
{
return sProjectName;
}
set
{
//optionally, you could prevent updates with:
//if (string.IsNullOrEmpty(sProjectName))
sProjectName= value;
//else throw Exception("ProjectName was already set!");
}
}
[Edit - I read the code a bit too fast, so this is what I actually meant:]
The purpose of the (poorly named IMHO) method ToString is to return the name of a file corresponding to a certain project name. There is nothing wrong with that, although it may be a responsibility which might belong to a separated class.
You could, for example, refactor the code to express its intention more clearly:
interface ISqlFileNameProvider
{
string SqlFilename { get; }
}
Then have a simple ("poor man's") implementation:
public class SimpleSqlFileNameProvider : ISqlFileNameProvider
{
private readonly string _filename;
public SimpleSqlFileNameProvider(string filename)
{
_filename = filename;
}
public string SqlFilename
{
get { return _filename; }
}
}
And then derive specialized implementation from here:
public class TemplateSqlFileNameProvider : SimpleSqlFileNameProvider
{
public TemplateSqlFileNameProvider(string template, string projectName)
: base(template.Replace("%project_name%", projectName))
{ }
}
public class CrByAuthorsFileNameProvider : TemplateSqlFileNameProvider
{
public CrByAuthorsFileNameProvider(string projectName)
: base("Changes_CR_By_Authors_%project_name%.txt", projectName)
{ }
}
public class DocumentCrMetricsFileNameProvider : TemplateSqlFileNameProvider
{
public DocumentCrMetricsFileNameProvider(string projectName)
: base("Changes_Document_CR_Output_%project_name%.txt", projectName)
{ }
}
First, note that projectName remains the parameter for the constructor of these specialized classes. There are no globals here. Next, even though you've added a bit of plumbing code to your project, it's easier to decouple your classes for simpler testing: you can create a mocked implementation of ISqlFileNameProvider and return whatever you like to test the rest of the functionality without writing to real data files.
I would certainly advise against using a global property. The fact that you can specify the project name as a constructor parameter means that you can easily test that your class behaves the way you want it to. And even though you think that it will change during project lifetime, you can easily encounter a scenario where you temporarily need to switch the project name in runtime. I would advise against using globals.

Generate custom properties code i VS?

I hate writing repetitive code....
In my current project I need to write properties that looks the same in each class, but different from class to class.
My wish is to generate custom properties from private memeber variables. Lets say I have declared a Name variable like this.
private string Name;
In my first class I want to automagically generate a property like this:
private string m_name;
public string Name
{
get
{ return m_name; }
set
{
m_name = value;
// some code....e.g.
m_counter++;
}
And maybe I want another implementation in my second class, e.g.
private string m_name;
public string Name
{
get
{ return m_name; }
set
{
// some code....e.g.
if(MyValidationFramework.Validate("Name", value))
{
m_name = value;
}
}
I know I can create my own snippets. Since I often change the property-implementation I'd like a way to generate the properties from a template, then change the template and generate properties again. Can this be done?
Thanks!
This is not direct answer to you question. However, with the example you show, why not to have a base class and inherit from it, like this:
public abstract class BaseClass
{
private string m_name;
public string Name
{
get { return m_name; }
set
{
if (BeforeNameSet(value))
m_name = value;
}
}
public virtual bool BeforeNameSet(string name)
{
return true;
}
}
public abstract class ChildClass : BaseClass
{
public override bool BeforeNameSet(string name)
{
// do the part that is different
return false;
}
}
[Edit]
I see you that snippets are not an option for you.
You could create an item template, (How to: Manually Create Item Templates), but in the end this is even more effort as you want to be able to dynamically update those. Item template is a zip file, that you would need to change content for.
Seems like copy/paste is your best option then.

ASP.NET Web Service DTO Properties vs Public Variables

I have a web service that will return a List where Person is a DTO. Is there any reason I shouldn't define Person like:
public class Person {
public string Name;
public string Email;
}
instead of
public class Person {
private string _name;
public string Name {
get {
return _name;
}
set {
_name = value;
}
}
}
The second version is more verbose, and I can't see any reason public instance variables could be a problem here. Any reason it could be?
Properties are preferred over fields to support
binding; fields cannot be bound
polymorphism; you can't do public virtual string Name;
You can use automatic properties to reduce the verbosity
public class Person {
public string Name { get; set; }
public string Email { get; set; }
}
In general - this is a design decision - see: http://forums.asp.net/t/1233827.aspx
But the DTO implementation is slightly different. Since this is just a DTO and there is no behavior with no set/get property specific implementation the usage you could just as well use the less verbose method. Any implementation change would not require client recompiles since they will be serialized the same way in either case via a service, so your smaller implementation is fine.
Fyi though - if the client is going to use these classes for databinding then they need to be properties in the class. Fields won't be bound.
In addition to all of the other answers, properties allow for validation to be ran when the property is read from or written to. That would take more work to do when using fields.

C#, accessing a variable from a class?

Say i have
public int MyVariable;
in the Form1.cs file, and I want to access it from Class1.cs , what do you think would be the best way to do that?
Thanks!
MSDN: Properties
base class with property:
class Person
{
private string name; // the name field
public string Name // the Name property
{
get
{
return name;
}
set
{
name = value;
}
}
}
Auto Implemented Properties (if advanced work on "name" isn't needed):
class Person
{
public string Name { get; set; } // the Name property with hidden backing field
}
Class accessing the property:
Person person = new Person();
person.Name = "Joe"; // the set accessor is invoked here
System.Console.Write(person.Name); // the get accessor is invoked here
It depends on the scenario. But ideally, Form elements are passed to any functions that will need to use them.
You have a few options:
Pass the value to the class/method that's using it. This is the preferred scenario. If your class depends on this value, supply the value to the class. Don't make the class go looking for it. (See: Dependency Inversion Principle)
Make the value static. Then any other class can refer to that value. Note the difference between instance and static, of course. The value will always be the same and needs to be given in the definition of the member, not in a constructor or other logic.
Create an instance of the form (which is itself just a class) within the class and access the public member on that instance. This is unlikely to be what you want because the instance you're creating isn't the instance that's running "on the page." (It also violates the principle noted above.)
Pass a reference to the form (this) to the class and refer to the member from that reference.
On a side note, you'll want to get in the habit of making your public members properties instead of variables. In most cases, the property will likely just get/set the variable and nothing more. However, if something more ever needs to be added it can be done so without breaking compatibility. Changing a variable to a property changes the footprint of the class and breaks things which use that class.
Make the variable static. Then you can call it like Form1.MyVariable.
Try like this:
In case (1) you can have MyClass.MyInt private readonly.
public class MyForm : System.Windows.Forms.Form
{
int myInt;
public MyForm()
{
myInt = 1;
//1
var myClass = new MyClass(myInt);
//2
myClass.MyInt = myInt;
}
}
public class MyClass
{
public int MyInt { get; set; }
public MyClass(int myInt)
{
MyInt = myInt;
}
}

Is a good practice to initialize private data members from within ctor by calling the associated properties instead of the data members themselves?

interface IAnimal
{
string Name { get; set; }
}
class Dog : IAnimal
{
private string name;
public Dog(string name)
{
Name = name;
}
public string Name
{
get { return name; }
set { name = value; }
}
}
In general, it's better to go through the property getter and setter whenever possible unless there is a specific reason not to. If the property setter has a side effect (like firing a notification) that you don't want in a specific situation, it's ok to assign to the backing field directly from within the object, but try to avoid getting into that sort of situation.
The reason it's good to use the property getter and setter, even in the implementing class itself: when/if you need to change the implementation of the getter/setter in the future, such as adding needed side effects, your code will already be in a good position to honor the new getter/setter semantics.

Categories

Resources