What is the syntax in C# for creating setters and getters? - c#-3.0

I'm familiar with this new syntax sugar:
public string Name { get; set; }
But what if I was the setter of that variable to have some sort of checking. For example, I want to convert the entire string that is supposed to be Set to all lowercases.
public string Name
{
get;
set
{
????
}
}

You will need a backing field for both the getter and setter (you can't have a partially automatic property):
private string name;
public string Name
{
get
{
return name;
}
set
{
// do validation or other stuff
name = value.ToLower();
}
}

You can't define a partially-automatic property. You would have to do things the old fashioned way: define backing field and implement the getter and setter logic yourself.

private string _name;
public string Name
{
get {return _name;}
set
{
_name = value.ToLower();
}
}

Then you cannot use the auto generated get/set feature:
string _name;
public string Name {
set { _name = value.ToLower(); }
set { return _name; }
}

public string Name { get; set; } These are called Auto Implemented Properties. In C# 3 and later you can use this syntax for property. But if you want to do any operation on the value before setting, then this is not helpful . One more disadvantage is ,you have to use both set and get,you can't declare only getter. Alternate is to make the setter private. In your case, you have to use the older version of properties.
private string _name;
public string Name
{
get {return _name;}
set
{
//do any operation
_name = value.ToLower();
}
}

Related

Computed Properties in Prism

What is the best way of doing computed properties in the Prism MVVM framework? I've got a Xamarin.Forms app with the following properties on a VM:
private string _title;
public string Title
{
get { return _title; }
set
{
SetProperty(ref _title, value);
OnPropertyChanged(() => Message);
}
}
private string _name = "John";
public string Name
{
get { return _name; }
set
{
SetProperty(ref _name, value);
OnPropertyChanged(() => Message);
}
}
public string Message
{
get { return String.Format("{0},{1}", Name, Title); }
}
The code works just fine. However, the Prism library is warning me on the OnPropertyChanged statements to use RaisePropertyChanged which will avoid the use of magic strings and that OnPropertyChanged with an expression is less efficient.
Is there some other method to notify the view to re-read "Message" whenever name or title change?
It got me to thinking maybe Prism has a way to set things up so that "Name" and "Title" don't have to be aware of Message in order for Message to be updated. This would be preferable if possible. What is the "Prism" way of doing computed properties? I cannot find any examples of it in their Xamarin.Forms documentation.
If you're trying to do this the harder way you can do something like the following:
public class FooViewModel : BindableBase
{
private string _foo;
public string Foo
{
get => _foo;
set => SetProperty(ref _foo, value, () => RaisePropertyChanged(nameof(FooBar)));
}
public string FooBar => $"{Foo} Bar";
}
If you want to make your life a little easier, install PropertyChanged.Fody and you can just have a ViewModel like the following:
public class SomeViewModel : BindableBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName => $"{FirstName} {LastName}";
}
Fody should give you an empty Weavers.xml, you'll just want to update it to look like:
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<PropertyChanged EventInvokerNames="RaisePropertyChanged" />
</Weavers>

partial class with interface with it

I am having two namespaces with two classes with same Name something like this "public partial class CustomerDetail" one from "namespace MS.Client" which implements "IClient" Interface and another one from "namespace MS.Customer" which implements "ICustomerInfo" Interface both in different assembly as well. am trying to access "CustomerDetail" from some other "namespace MS.Applications.View" which has a reference for "namespace MS.Client" but when I suppose to instantiate the "CustomerDetail" class in "namespace MS.Applications.View" I would except all the properties that belongs to "CustomerDetail" in all the namespaces correct? but it was not actually working. can any one help me out from this?
namespace MS.Client
{
public partial class CustomerDetail : IClient
{
private string name;
public string CustName
{
get { return name; }
set { name = value; }
}
private string address;
public string CustAddress
{
get { return address; }
set { address = value; }
}
}
}
namespace MS.Customer
{
public partial class CustomerDetail : ICustomerInfo
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string address;
public string Address
{
get { return address; }
set { address = value; }
}
}
}
please let me know if any one cant understand my summary.
No, classes are local to their namespaces and thus, you can not modify a class from a different namespace. All classes have a fully qualified name, which is their real name, and the namespace is part of it.
What you are actually doing in your code is defining two different CustomerDetail classes, each in a different namespace, effectively being: MS.Customer.CustomerDetail and MS.Client.CustomerDetail.
In order to achieve what you are trying, you need to change to change one of the namespaces so they actually match and the CustomerDetail are actually the same (i.e. they have the same fully qualified name since they are prefixed by the same namespace and have the same name).

what is use of creating property in separate class for each entilty?

I am learning some good code practice that's why i was going through some code, some thing i could not understand in it. It has made property in a separate class for each entity like in userClass it has property
#region public properties
private int uid;
public int userId
{
get { return uid; }
set { uid = value; }
}
private string uName;
public string userName
{
get { return uName; }
set { uName = value; }
}
private string pwd;
public string password
{
get { return pwd; }
// set { pwd = value; }
}
private string uAddress;
public string userAddress
{
get { return uAddress; }
set { uAddress = value; }
}
private string fName;
public string firstName
{
get { return fName; }
set { fName = value; }
}
private string lName;
public string lastName
{
get { return lName; }
set { lName = value; }
}
private string uPhone;
public string userPhone
{
get { return uPhone; }
set { uPhone = value; }
}
private string uMobile;
public string userMobile
{
get { return uMobile; }
set { uMobile = value; }
}
private int secretQuestion;
public int securityQuestion
{
get { return secretQuestion; }
set { secretQuestion = value; }
}
private string userAnswer;
public string answer
{
get { return userAnswer; }
set { userAnswer = value; }
}
#endregion
and from the business logic class it uses the property instead of using directly any entity's attribute name, but i am confuse whats there need to make a property like this?
other then this it has got enums for database column name which has a clear reason behind this that if in near future we have to change the database table's fields name then we don't have to change through out the whole business logic class and we can make changes to enum directly, But what is there use of creating property like this please elaborate me on this
Are you really asking why it uses properties instead of having public fields?
Fields are an implementation detail - they're how data is stored, which shouldn't be something the outside world cares about, at least for 99% of types. Properties are part of the contract that a type has in terms of its API - the implementation is up to the type. In other words, it's a matter of encapsulation. Properties can be expressed in interfaces, as abstract methods etc, precisely because they keep the contract and the implementation separate.
Additionally, properties make databinding, debugging and various other things simpler. I have an article about why properties matter, which you may find useful.
Having said all of this, those properties are implemented in a tedious way - and they don't obey .NET naming conventions. I would have written them as:
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
// etc
Properties can be defined on Interfaces, but member fields cannot. So if you needed to refactor this class to a class that implements an interface, you can put the properties on the interface (and then have other classes that implement them as well.)
Some similar questions:
Public Fields versus Automatic Properties
Property vs public field.
In additional to above: Actually you can easily decide public field or property by yourself. It is quite easier to understand that:
(1) Name is a property of class Person
(2) Speed is a property of class Plane
(3) Empty is a public field of class String. If you say String has a property named Empty, it's really weird. And String has a property Length is easy to understand.

MVC2: Validation (Data Annotations) with two field dependency

Example:
We have a conditional field.
This conditional field is a radio button with the following two values “yes” and “no”.
Lets say the name of this radiobutton is “AAA”.
This conditional field “AAA” should only be displayed when another radio button field “BBB” is set to “yes”. (Values of radio button “BBB” are also “yes” and no”) .
But the conditional field “AAA” should be displayed with NO pre-set value, means “yes” nor “no” should be set when the field is first displayed.
The problem occurs based on the requirement that the conditional field “AAA” should ONLY be required when (the non-conditional) field “BBB” is set to “yes” – and not required when the field “BBB” is set to “no”.
(Sounds, that I didn’t heard anything about an if statement, or? But hold on and continue reading ...)
Believe me, it would not be a problem for me to solve this topic when we would use the “Modelstate” – but we are talking here about Validation (Data Annotations) that looks like this here:
public class Input1FormModel
{
[Required(ErrorMessageResourceName="Error_Field_AAA_Empty",
ErrorMessageResourceType=typeof(Resources.MyDialog))]
public int AAA { get; set; }
}
I fully understand ALSO these lines of code - I believe ;-)
...
//property limits
public int UpperBound { get { return DateTime.Now.Year; } }
public int LowerBound { get { return 1900; } }
...
[NotNullValidator]
[PropertyComparisonValidator("LowerBound", ComparisonOperator.GreaterThan)]
[PropertyComparisonValidator("UpperBound", ComparisonOperator.LessThanEqual)]
public int? XYZ { get; set; }
But, how to solve the above described dependency (AAA <-> BBB)?
Changing “return DateTime.Now.Year;” to a function call which checks first the other field and returns then true or false? But how to fetch there the value of the other field?
You may need to use IDataErrorInfo.
See this question, where I answered this:
Check out IDataErrorInfo and this question I asked about IDataErrorInfo vs. DataAnnotations.
You can do this using data annotations but the annotation needs to be operating on the class level and not on the property level as validationattributes are for single properties.
Here is an example I created because post code is optional and state not required if people have said they're in New Zealand, but it is compulsory in Australia. This composite validation with take the whole model as the input value and use reflection to compare the values of the property names passed in from the data annotation.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class NZPostcodeAttribute : ValidationAttribute
{
public const string _defaultErrorMessage = "Postcode and State are required for Australian residents";
private readonly object _typeId = new object();
public NZPostcodeAttribute(string countryProperty, string postcodeProperty, string stateProperty)
{
CountryProperty = countryProperty;
PostcodeProperty = postcodeProperty;
StateProperty = stateProperty;
}
public string CountryProperty { get; private set; }
public string StateProperty { get; private set; }
public string PostcodeProperty { get; private set; }
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return _defaultErrorMessage;
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value);
object countryValue = props.Find(CountryProperty, true).GetValue(value);
object postcodeValue = props.Find(PostcodeProperty, true).GetValue(value);
object stateValue = props.Find(StateProperty, true).GetValue(value);
string countryString = countryValue == null ? "" : countryValue.ToString();
string postcodeString = postcodeValue == null ? "" : postcodeValue.ToString();
string stateString = stateValue == null ? "" : stateValue.ToString();
bool isValid = true;
if (countryString.ToString().ToLower() == "australia")
{
if (String.IsNullOrEmpty(postcodeString) || String.IsNullOrEmpty(stateString))
{
isValid = false;
}
}
if (!String.IsNullOrEmpty(postcodeString))
{
string isNumeric = "^[0-9]+";
if (!Regex.IsMatch(postcodeString, isNumeric))
isValid = false;
}
return isValid;
}
}
When you want to apply this to your model, it needs to be done on a class level on the model (see the flag AttributeTargets.Class at the top).
Do it as follows:
[NZPostcode("Country", "Postcode", "State")]
public class UserRegistrationModel
{....
You need to point the validation attribute to the property names. It is also possible to add client side validation to this as well, but that would be a whole article on its own.
You can easily adapt the above to your scenario.

Auto-properties: Checking/validating during the "set"

I think we can all agree that Automatic Properties in C# 3.0 are great. Something like this:
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
Gets reduced to this:
public string Name { get; set; }
Lovely!
But what am I supposed to do if I want to, say, convert the Name string using the ToUpperInvariant() method while "setting". Do I need to revert back to the old C# 2.0 style of creating properties?
private string name;
public string Name
{
get { return name; }
set { name = value.ToUpperInvariant(); }
}
Or is there a more elegant way of accomplishing this?
Yes, you have to convert it back. An autoproperty can't do this kind of checks.