Automatic Property Values and Defaults [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you give a C# Auto-Property a default value?
I have a property in a class like so
public String fontWeight { get; set; }
I want it's default to be of "Normal"
Is there a way to do this in "automatic" style rather than the following
public String fontWeight {
get { return fontWeight; }
set { if (value!=null) { fontWeight = value; } else { fontWeight = "Normal"; } }
}

Yes you can.
If your looking for something like:
[DefaultValue("Normal")]
public String FontWeight
{
get;
set;
}
Do a google search for 'Aspect Oriented Programming using .NET'
..if this is overkill for you do this:
private string fontWeight;
public String FontWeight {
get
{
return fontWeight ?? "Normal";
}
set {fontWeight = value;}
}

No, an automatic property is just a plain getter and/or setter and a backing variable. If you want to put any kind of logic in the property, you have to use the regular property syntax.
You can use the ?? operator to make it a bit shorter, though:
private string _fontWeight;
public String FontWeight {
get { return _fontWeight; }
set { _fontWeight = value ?? "Normal"; }
}
Note that the setter is not used to initialise the property, so if you don't set the value in the constructor (or assign a value in the variable declaration), the default value is still null. You could make the check in the getter instead to get around this:
private string _fontWeight;
public String FontWeight {
get { return _fontWeight ?? "Normal"; }
set { _fontWeight = value; }
}

You will need to use a backing field.
private string fontWeight;
public String FontWeight
{
get { String.IsNullOrEmpty(fontWeight) ? "Normal" : fontWeight;}
set {fontWeight = String.IsNullOrEmpty(value) ? "Normal" : value;}
}

You either need to use a backing field and initialize that to your default value
private String fontWeight = "Normal";
public String FontWeight
{
get { return fontWeight; }
set { fontWeight = value; }
}
or, keep the auto property and call the setter in your constructor
public constructor()
{
FontWeight = "Normal";
}
public String FontWeight { get; set; }

One way to do it is using PostSharp as detailed in this answer to a similar question.

You could use the DefaultValue attribute:
[DefaultValue("Normal")]
public string FontWeight { get; set; }
Although it notes that
A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.
so you could use this in conjunction with initialisation in the constructor or via a backing field and default handling.

You'd need either a variable like so:
string fontWeight;
public string FontWeight
{
get
{
if (string.IsNullOrEmpty(fontWeight))
fontWeight = "Normal";
return fontWeight;
}
set { fontWeight = value; }
}
Or use a Constructer to set an initial value:
class FontClass
{
public string FontWeight { get; set; }
public FontClass()
{
FontWeight = "Normal";
}
}

Related

Backing a public property with a private property?

I'm looking at some code and found this kind of pattern:
private string text { get; set; }
public string Text
{
get
{
return text;
}
set
{
text= value;
RaisePropertyChanged("Text");
}
}
I normally just back my public properties with private fields.
Is there any reason a property should be backed by a private property like this? My instinct is to say that it shouldn't, and this should be backed by a field instead, is that right? Any technical reasons I can use to back this up?
Typical case is when you have a raw data (data as it is without any transformation) and the same data, but friendly represented:
private String m_RawText;
// Text as it's obtained from, say, database
private string rawText {
get {
if (null == m_RawText)
m_RawText = ReadValueFromDataBase();
return m_RawText;
}
set {
if (m_RawText != value) {
UpdateValueInDataBase(value);
m_RawText = value;
}
}
}
// Friendly encoded text, for say UI
public string Text {
get {
return EncondeText(rawTex);
}
set {
rawText = DecodeText(value);
RaisePropertyChanged("Text");
}
}
// Here we want rawText
public void PerformSomething() {
String text = rawText; // we want raw text...
...
}
// And here we prefer Text
public override String ToString() {
return String.Fromat("Text = {0} ", Text, ...)
}

Change .NET Property Grid readonly attribute at runtime

I have a property grid that i wanna change readonly attribute of some of its items at run-time.
Changing readonly for simple items is easy and i have no problem there, my problem is i cannot change readonly for hierarchical items like latitude and longitude in picture below. I even tried to make the whole "Position" category readonly but it didn't seem to help.
Side question: Is there any way to put some items in a group (like this position item) without wrapping them in a class?
Yes! This could be helpful!
public class Member
{
string name;
bool isMarried;
string spouseName;
public string Name
{
get { return name; }
set { name = value; }
}
[System.ComponentModel.RefreshProperties(RefreshProperties.All)]
public bool IsMarried
{
get { return isMarried; }
set
{
isMarried = value;
bool newValue = !value;
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this.GetType())["SpouseName"];
ReadOnlyAttribute attrib = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];
FieldInfo isReadOnly = attrib.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
isReadOnly.SetValue(attrib, newValue);
}
}
[ReadOnly(true)]
public string SpouseName
{
get { return spouseName; }
set
{
spouseName = value;
}
}
}

forcing a variable to hold certain values only

I am using vs 2012. I have a simple string property
string _someString;
public string MyString
{
get
{
return _someString;
}
}
I want this property to hold only certain values. So that when the client uses this property only those certain values can be used.
It sounds like what you really want is an enum:
public enum MyValues //TODO rename all the things
{
SomeValue,
SomeOtherValue,
FinalValue,
}
Then your property can be:
private MyValues value;
public MyValues MyValue
{
get { return value; }
}
If you need to get a string representation of that value just call ToString on the enum value:
string stringValue = value.ToString();
Use an enum as in :
enum MyEnum
{
AllowableValue#1,
AllowableValue#2,
...
}
public MyEnum myEnum { get; set; }
Then populate some UI element with only the values of the enum.
I suppose you want to have some validation on the setter then:
public string MyString
{
get
{
return _someString;
}
set
{
if (value == "a" || value == "b" /* ... */)
_someString = value;
else
throw new InvalidArgumentException("Invalid value!");
}
}
Make sure to set it via the property, not the actual member variable.

add two value to combobox

In c# we can add a text and a value to each items of combobox, I want to know is it possible in Java also? if not please advice.
I Solved my problem by create a class like
public class ItemInfo {
public String Name;
public String Value;
public ItemInfo(String Name , String Value) {
this.Name = Name;
this.Value = Value;
}
public String toString() {
return Name ;
}
public String getValue() {
return Value ;
}
}
than I just create a new object from this class & pass it to my combobox
combbox1.addItem(new ItemInfo(item[0],item[1]));
job done :)!
You should learn how to use ComboBox in java.

Using accessors in C# stack overflow

From http://msdn.microsoft.com/en-us/library/aa287786(v=vs.71).aspx
public string Name { get {
return name; } set {
name = value; } }
So why is it that when I set the value as so:
public int numHighAttacksHit
{
get { return numHighAttacksHit - handicapHighAttacks; }
set { numHighAttacksHit = value; }
}
this.numHighAttacksHit = 0;
It keeps circling around again and again setting value to numHighAttacksHit until I reach a stack overflow? This is within the same class, does that matter?
screenshot: http://gyazo.com/a49757753acfbb5b51aaef5be033c948.png
The property needs a field to reference, like this:
private int numHighAttacksHit;
public int NumHighAttacksHit // <-- note the pascal case
{
get { return numHighAttacksHit - handicapHighAttacks; }
set { numHighAttacksHit = value; }
}
this.NumHighAttacksHit = 0;
You are referencing the property inside of it's definition causing the stack overflow, unlike the example from MSDN.
try
private int numHighAttacksHit;
public int NumHighAttacksHit
{
get { return numHighAttacksHit - handicapHighAttacks; }
set { numHighAttacksHit = value; }
}
C# is case sensitive: Name and name are two different things, and in the MSDN article it has name defined as a private field:
private string name; // the name field
public string Name // the Name property
{
get
{
return name;
}
}
In your example, you don't have that private field, so numHighAttacksHit is going in a loop accessing itself.
You are returning the value of the property numHighAttacksHit within the property numHighAttacksHit itself--this creates a non-terminating recursion and is the source of your stack overflow.
Because in the second one, you are setting numHighAttacksHit again and again, and in the first one you are setting the value to name variable not to the property.

Categories

Resources