How does PropertyDescriptor.ResetValue Method determine default value of property - c#

I have implemented a custom class and tried to set its default value by calling PropertyDescriptor.ResetValue Method. When i make some researches in internet, i saw a link in msdn about this method, its usage and how can be used.
http://msdn.microsoft.com/en-us/library/system.componentmodel.propertydescriptor.resetvalue.aspx
According to this link, msdn document says:
This method determines the value to reset the property to in the following order of precedence:
1- There is a shadowed property for this property.
2- There is a DefaultValueAttribute for this property.
3- There is a "ResetMyProperty" method that you have implemented, where "MyProperty" is the name of the property you pass to it.
Second methodology does not correspond to my needs. On the other hand, there are not enough usage samples of first and third items.
Could you please explain expecially third one?

I don't know about the first option (I suspect it's to do with declaring one property in a base class and a "new" property in a derived class), but the third seems pretty simple to me:
public class Foo
{
public string Name { get; set; }
public Foo()
{
ResetName();
}
public void ResetName()
{
Name = "Some default value";
}
}
The documentation is saying that if you call ResetValue on the PropertyDescriptor for the Name property, it will call the ResetName method on the component.
I've never actually tried this, but that would be my interpretation.

You can retrieve (2) DefaultValueAttribute like this:
public class MyClass
{
[DefaultValue("my default value")]
public string MyVar { get; set; }
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(typeof(MyClass)))
string defaultValue = descriptor.Attributes.OfType<DefaultValueAttribute>().First().Value.ToString();

Related

Roslyn - SyntaxGenerator, generate AutoProperty

Is it somehow possible to generate an auto-property with the Roslyn SyntaxGenerator class (NOT SyntaxFactory)?
This:
var myProperty = generator.PropertyDeclaration("MyProperty", generator.TypeExpression(SpecialType.System_String), Accessibility.Public);
will generate:
public string MyProperty {
get {
}
set {
}
}
I would like to have:
public string MyProperty { get; set; }
Is this possible with some option? I found some solutions which uses SyntaxFactory, but i would like to use SyntaxGenerator.
I don't think that is possible.
If you take a look at the source for PropertyDeclaration you will notice, that unless the getter/setter is not declared or the property is abstract any getAccessorStatements/setAccessorStatements passed as null are set to an empty IEnumerable.
The generation of the accessors-statements then uses the AccessorDeclaration which will either return the accessors with a body (if the accessor is declared as null) or with a semicolon (if it is not null which is only possible for abstract properties as noted above).
There also seems to be an open issue on github on this.

Is there any way to implement a get method inside a class in C#?

I would like to know if there is any way to implement a get method inside a class?
public class Element: IWebElement
{
IWebElement realElement;
//Question point is this get{}
//Everytime I access the instance of this class this get would be called
get
{
//This 'realElement' is not present yet
//So I cannot initialize it
//But when the properties of this class are accessed
//I'm telling the get method that it's time to initialize 'realElement'
realElement = webDriver.FindElement(...);
Visible = element.Visible;
return this;
}
public bool Visible {get; set;}
}
public class AnotherClass()
{
public void AccessElement()
{
Element element = new Element();
if(element.Visible) // At this point the 'element'
{
}
}
}
Usage:
I cannot initialize every property with their own get, because they are too many
Everytime I access the instance of this class this get would be called
If that could be done you'd be in trouble returning this since that would then access the instance, which would call the method, which would then access the instance, which would call the method… and so on until you get a StackOverflowException (or if it got tail-call optimised, forever).
More generally the question doesn't make sense.
A get method is a method identified as being the getter of a property. When C# is compiled to CIL then properties with getters are compiled so that there is a .property declaration with a .get declaration that refers to that method. If C# decided to change the rules to have getters on classes, it wouldn't have any corresponding CIL to compile it to.
The closest thing to a getter on a class in .NET is a default property, which in C# you can only have (and will always have) on a property called this (it becomes what is visible to other .NET languages or reflection property called Item), but it must have an indexer, and it does still exist as a property rather than with the getter directly applied to the class.
You could use the constructor, so it will be called everytime instance of object will be created.
public class Element()
{
public Element(){
AnyProperty = ""; //some value initialize
}
}
Added this new answer with my old answer because I got downvoted for trying to answer your original code which is now really different. Sheesh.
Usage: I cannot initialize every property with their own get, because
they are too many
So, this is actually not how you usually use get. Get is used mostly for access to a private method, or with a little logic, and oftentimes for data-binding such as in MVVM, etc.
I think your wording is not accurate. You said
Everytime I access the instance of this class this get would be called
But based on your code, what you mean is "Everytime I instantiate a class". The only thing you really need is a constructor.
public class Element: IWebElement
{
IWebElement realElement;
public bool Visible {get; set;}
public Element()
{
realElement = webDriver.FindElement(...);
Visible = element.Visible;
}
}
Old answer:
You're probably thinking of the Singleton Pattern
EDIT: This originally answered original question's code, seen below.
public class Element()
{
//Question point is this get{}
//Everytime I access the instance of this class this get would be called
get{
return this;
}
public string AnyProperty {get; set;}
}
public class AnotherClass()
{
public void AccessElement()
{
Element element = new Element();
element.AnyProperty = "";
}
}

What is the meaning of "get"? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C# what does this code with “get” mean?
I'm using open source project. In this project there is function.
public virtual ICollection<Customer> AffiliatedCustomers
{
get
{
return _affiliatedCustomers ?? (_affiliatedCustomers = new List<Customer>());
}
protected set { _affiliatedCustomers = value; }
}
I don't understand what is the meaning of "get".
Can you please explain this function.
AffiliatedCustomers is a property.
The get defines the property getter, which is a method used internally to return the value by the property. It allows you to use this given an instance of the class like so:
var customers = theClass.AffiliatedCustomers; // Looks like a field, but is a property
Properties can also have a set section, as well, as this one does (protected set { _affiliatedCustomers = value; }), which gives you control over what happens when you set the value via the Property.
For details, see Properties in C#.
This is not a function. It is a property. A property is basically a fancy wrapper for some variable. For example, declaring the following property:
public string SomeProperty { get; set; }
will actually compile to something like this:
private string backing_SomeProperty;
public void set_SomeProperty(string value)
{
backing_SomeProperty = value;
}
public int get_SomeProperty()
{
return backing_SomeProperty;
}
That's an example of an automatic property. Of course, you can also define the getter and setter methods yourself like this:
public string SomeProperty
{
get
{
// some logic code here
// then return some value
}
set
{
// some logic code here
// then set some value
}
}
This is a property,
Quoted by msdn:
Properties are members that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can be used as though they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily while still providing the safety and flexibility of methods.
Please refer to this link for more:
http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx
Properties have a getter and a setter - their purpose is obvious (to get and set the value of the property).
When you use auto properties, there is still a get and a set, but the backing variable is automatically implemented for you. In the example you have given the author of the code has chosen to have their own implementation of the get - in this case to automatically initialise the member variable the first time the property is accessed.

Work with Custom Attributes on my C# POCO class

In my project I have one class called Area like below.
The property "CodArea" I want to put one custom attribute like [NaoSelecionarAttr(true)].
This is working fine but when I create one instance of the class I can not get this custom attribute. Something like this:
Area areaPoco = new Area();
areaPoco.CodArea.GetType().GetCustomAttributes(typeof(NaoSelecionarAttr),true).ToList();
[Serializable]
public class Area
{
#region Private Members
private decimal _numChave;
private string _codArea;
public Area()
{
_numChave = 0;
_codArea = null;
}
public Area(decimal pNumChave, string pCodArea)
{
NumChave = pNumChave;
CodArea = pCodArea;
}
public virtual decimal NumChave
{ get { return _numChave;}
set { _numChave = value;}
}
[NaoSelecionarAttr(true)]
public virtual string CodArea
{
get { return _codArea; }
set { _codArea = value;}
}
}
public class NaoSelecionarAttr : Attribute
{
public bool NaoSelecionar { get; set; }
public NaoSelecionarAttr(bool pSim) { this.NaoSelecionar = pSim; }
}
}
There are some problems with your code.
The first problem in the code is that you are calling the default constructor on Area, which initializes _codArea to null. And then you try to call GetType on it, which fails with a NullReferenceException, as expected.
The second problem is that you want an attribute of a property of a class. So you must inspect (or reflect) the class, not the property. You see, when you write areaPoco.CodArea... the compiler resolves it to the result of your get expression, in this case, the field _codArea. By calling GetType() on _codArea, what you retrieve is a String type, not your Area type. I know this may seem confusing at first, but properties aren't types, so you can't reflect on them.
What you should do, then, is:
Area areaPoco = new Area();
NaoSelecionarAttr attr = (NaoSelecionarAttr) (areaPoco.GetType().GetProperties().Single(p => p.Name == "CodArea").GetCustomAttributes(typeof(NaoSelecionarAttr), true).Single());
bool naoSelecionar = attr.NaoSelecionar;
If I may, I want to give you some tips as well:
Your notation for the non-default constructor seems reminiscent of C/C++. There usually isn't a good reason to stick a "p" prefix in the parameters.
Instead of NaoSelecionar, which is a negative property, I recommend you work with "Selecionar". The deal is that you can easily confuse a negative sentence with its correspondent positive one. A month from now you will ask, "ok, the parameter is false, so should I select or not this property?". False usually means NOT, so, your default interpretation would be not to select something when the property is false.
Your default constructor is initializing a property to null. Just as I described above, this can result in bugs. Either initialize it to a default value (string.Empty), or remove the default constructor and use only the one that requires the user to provide a value to string. And validate those parameters as well -- the user might provide again a null to the string. (An object should be valid when first constructed)
One final tip. Your NaoSelecionar attribute gets a boolean parameter. The last bullet was exactly about that -- you can confuse whether having a true property for your attribute means "não" or "sim". Well, why don't you simply remove the parameter and then work with a negative parameter? There's no need to pass true or false to NaoSelecionar, since all you need to do is iterate through your class and find which properties have this attribute applied to them.
Why do you use areaPoco.CodArea.GetType()? I think you should use areaPoco.GetType(). Because your custom attribute belongs to the Area class, not to the string.

How to make a property required in c#?

I have requirement in a custom class where I want to make one of my properties required.
How can I make the following property required?
public string DocumentType
{
get
{
return _documentType;
}
set
{
_documentType = value;
}
}
If you mean "the user must specify a value", then force it via the constructor:
public YourType(string documentType) {
DocumentType = documentType; // TODO validation; can it be null? blank?
}
public string DocumentType {get;private set;}
Now you can't create an instance without specifying the document type, and it can't be removed after that time. You could also allow the set but validate:
public YourType(string documentType) {
DocumentType = documentType;
}
private string documentType;
public string DocumentType {
get { return documentType; }
set {
// TODO: validate
documentType = value;
}
}
.NET 7 or newer
Syntax
public class MyClass
{
public required string Name { get; init; }
}
new MyClass(); // illegal
new MyClass { Name = "Me" }; // works fine
Remarks
The required properties must declare a setter (either init or set).
Access modifiers on properties or setters cannot be less visible than their containing type, as they would make impossible to initialize the class in some cases.
public class MyClass
{
internal required string Name { get; set; } // illegal
}
Documentation
Official documentation here
Feature demo here
.NET 6 or older
See this answer
If you mean you want it always to have been given a value by the client code, then your best bet is to require it as a parameter in the constructor:
class SomeClass
{
private string _documentType;
public string DocumentType
{
get
{
return _documentType;
}
set
{
_documentType = value;
}
}
public SomeClass(string documentType)
{
DocumentType = documentType;
}
}
You can do your validation – if you need it – either in the property's set accessor body or in the constructor.
With the release of .NET 7 and C# 11 in November 2022 you can now use the required modifier this way:
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName) => FirstName = firstName;
public required string FirstName { get; init; }
public int Age { get; set; }
}
And when you don't have the required properties it will throw an error when you try to initialize an object.
For more information refer to:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#required-members
https://learn.microsoft.com/en-us/dotnet/csharp/properties#init-only
Add a required attribute to the property
Required(ErrorMessage = "DocumentTypeis required.")]
public string DocumentType
{
get
{
return _documentType;
}
set
{
_documentType = value;
}
}
For custom attribute detail Click Here
I used an other solution, not exactly what you want, but worked for me fine because I declare the object first and based on specific situation I have different values. I didnt want to use the constructor because I then had to use dummy data.
My solution was to create Private Sets on the class (public get) and you can only set the values on the object by methods. For example:
public void SetObject(string mandatory, string mandatory2, string optional = "", string optional2 = "")
This one liner works in C# 9:
public record Document(string DocumentType);
new Document(); // compiler error
new Document("csv"); // correct way to construct with required parameter
This explains how it works. In the above code, Document is the name of the class or "record". That first line of code actually defines an entire class. In addition to this solution essentially making a required DocumentType property (required by an auto implemented constructor), because it uses records, there are additional implications. So this may not always be an appropriate solution, and the C# 11 required keyword will still come in handy at times. Just using record types doesn't automatically make properties required. The above code is a special syntax way of using records that essentially has this effect as well as making the property init only and causes a deconstructor to be automatically implemented.
A better example would be using an int property instead of a string since a string could still be empty. Unfortunately I don't know of any good way to do extra validation within the record to make sure the string is not empty or an int is in range, etc. You would have to go deeper down the TOP (type driven development) rabbit hole, which may not be a bad thing. You could create your own type that doesn't allow empty strings or integers outside your accepted range. Unfortunately such an approach would lead to runtime discovery of invalid input instead of compile time. There might be a better way using static analysis and metadata, but I've been away from C# for too long to know anything about that.

Categories

Resources