I have come across a situation where I probably needed to add properties(of a class) in a list to invoke them manually(or you can say, I need to assign there values(setter)). That is why because, I don't even know which properties is to set the values, but they are decided at runtime. So far I am trying to find out the solution here and there but still I don't get any article that even hints me a work around for this purpose.
Here's what I want to do exactly (mentioned as comments)-
public class DemoClass
{
IList<Properties> _listOfProps;
private int _iFirstProperty;
private string _iSecondProperty;
public DemoClass()
{
_listOfProps = new List<Properties>();
}
public int FirstProperty
{
get
{
return _iFirstProperty;
}
set
{
_iFirstProperty = value;
// Here I want to add this property into the list.
_listOfProps.Add(FirstProperty);
RaisePropertyChanged("FirstProperty");
}
}
public string SecondProperty
{
get
{
return _iSecondProperty;
}
set
{
_iSecondProperty = value;
RaisePropertyChanged("SecondProperty");
}
}
public void HandleChangedProperties()
{
foreach (var list in _listOfProps)
{
// Here I want to invoke the property. ie. sets the 'value' of this property.
list.Invoke(value)
}
}
}
I know, I can use Func to add in the list like- but I can't go with this.
List<Func<int>> listOfFunc = new List<Func<int>>();
listOfFunc.Add(() => { return 0; }); // Adds using lambda expression
listOfFunc.Add(temp); // Adds as a delegate invoker
private int temp()
{
return 0;
}
from MSDN
Properties can be used as if they are public data members, but they
are actually special methods called accessors.
if properties are internally methods, Why they can't be added as List of Func<>
Also, if there's no way I can do that without using Reflection (by getting PropertyInfo list), why Microsoft hasn't designed this in C#?
You can either keep a list of PropertyInfo values and later set the value of the properties using reflection, or you can keep a list of setter delegates (which effectively just forward the value to the real, hidden setter).
For example:
IList<Action<object>> listOfSetters;
listOfSetters.Add(o => this.FirstProperty = (int)o);
// and then:
listOfSetters[0](42); // FirstProperty = 42
Related
I have this code:
public static class Settings
{
public static int Trk5 { get; set; }
}
Settings.Trk5 = 2;
db2.Update(new Setting { "Trk5", Value = val.ToString() });
Would it be a good idea to somehow combine the updating of the database with the setting of the variable and if so how could I do that?
Can I combine the db2.Update into the set; somehow?
You could let the property save itself in its setter (like #Alsein proposed). You would need to convert your auto-property to a full property for that.
Perhaps this might work:
public static class Settings
{
private static int trk5;
public static int Trk5
{
get { return trk5; }
set
{
if (trk5 != value)
{
trk5 = value;
db2.Update(new Setting { "Trk5", Value = value.ToString() });
}
}
}
}
Settings.Trk5 = 2;
However, I doubt if your db2.Update call will work this way. You are creating a new Setting instance there, but you did not specify the property name for the "Trk5" value...
You need to call the Update method within the property.
If you want it to be automatically applied to every single properties, consider the following solutions:
Make a proxy that raises the changing event dynamically at runtime.
Inserting the notification statically at build time.
In C#, is it possible to check if a Property has a Setter that references another object at runtime?
Here is some code:
private PropertyChanged _propertyChanged;
public string PropertyChangedName
{
get
{
return _propertyChanged.Name;
}
set
{
_propertyChanged.Name = value;
}
}
In the above code, the PropertyChangedName is referenced as part of the PropertyChanged object. When setting the PropertyChangedName, the _propertyChanged.Name is set.
Here is some code where the PropertyChangedName is not referenced as part of the PropertyChanged object:
private string _propertyChangedName;
public string PropertyChangedName
{
get
{
return _propertyChangedName;
}
set
{
_propertyChangedName = value;
}
}
I am not sure this is the best way, however, it might help you:
// store the current state:
var valuesbefore = new List<object>();
foreach (var r in this.GetType().GetFields(System.Reflection.BindingFlags.NonPublic))
valuesbefore.Add(r.GetValue(this));
// change the value the specified property
PropertyChangedName = PropertyChangedName + "a";
//get the new state of the class:
var valuesnow = new List<object>();
foreach (var r in this.GetType().GetFields(System.Reflection.BindingFlags.NonPublic))
valuesnow.Add(r.GetValue(this));
// check for any change
bool equal = valuesbefore.SequenceEqual(valuesnow);
If equal is false, it means that you are dealing with a case in which the setter changes the value of private field. Note that special care is required when dealing with types other than string, int, etc.
You could implement INotifyPropertyChanged and subscribe to it.
This is a really tricky question. The System.Reflection library in .NET allows you to observe the class signatures (Types, Fields, Methods, etc), invoke them, and get their values; but not see within their body.
Read through the answers in this question for some options to inspect the contents of methods. (a Property is just a method -- two if you have both get and set)
The C# "readonly" keyword is a modifier that when a field declaration includes it, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors, a lazy/late evaluation/initialization maybe.
How could I do that? and is it possible to do it in a nice way, for example, is it possible to write some attribute to describe this?
If I understand your question correctly, it sounds like you just want to set a field's value once (the first time), and not allow it to be set after that. If that is so, then all the previous posts about using Lazy (and related) may be useful. But if you don't want to use those suggestions, perhaps you can do something like this:
public class SetOnce<T>
{
private T mySetOnceField;
private bool isSet;
// used to determine if the value for
// this SetOnce object has already been set.
public bool IsSet
{
get { return isSet; }
}
// return true if this is the initial set,
// return false if this is after the initial set.
// alternatively, you could make it be a void method
// which would throw an exception upon any invocation after the first.
public bool SetValue(T value)
{
// or you can make thread-safe with a lock..
if (IsSet)
{
return false; // or throw exception.
}
else
{
mySetOnceField = value;
return isSet = true;
}
}
public T GetValue()
{
// returns default value of T if not set.
// Or, check if not IsSet, throw exception.
return mySetOnceField;
}
} // end SetOnce
public class MyClass
{
private SetOnce<int> myReadonlyField = new SetOnce<int>();
public void DoSomething(int number)
{
// say this is where u want to FIRST set ur 'field'...
// u could check if it's been set before by it's return value (or catching the exception).
if (myReadOnlyField.SetValue(number))
{
// we just now initialized it for the first time...
// u could use the value: int myNumber = myReadOnlyField.GetValue();
}
else
{
// field has already been set before...
}
} // end DoSomething
} // end MyClass
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors
Note that lazy initialization is complicated, so for all of these answers you should be careful if you have multiple threads trying to access your object.
If you want to do this inside the class
You can use the C# 4.0 built-in lazy initialization features:
http://msdn.microsoft.com/en-us/library/dd997286.aspx
http://msdn.microsoft.com/en-us/library/dd642331.aspx
http://sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt/
Or for older versions of C#, just supply a get method, and check if you're already initialized by using a backing field:
public string SomeValue
{
get
{
// Note: Not thread safe...
if(someValue == null)
{
someValue = InitializeSomeValue(); // Todo: Implement
}
return someValue;
}
}
If you want to do this outside the class
You want Popsicle Immutability:
http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx
http://msdn.microsoft.com/en-us/library/ms750509.aspx
http://csharpindepth.com/Talks.aspx (search for "popsicle immutability" and you'll find a video)
Basically:
You make the whole class writable, but add a Freeze method.
Once this freeze method is called, if users try to call setters or mutator methods on your class, you throw a ModifyFrozenObjectException.
You probably want a way for external classes to determine if your class IsFrozen.
BTW, I made up these names just now. My selections are admittedly poor, but there is no generically followed convention for this yet.
For now I'd recommend you create an IFreezable interface, and possibly related exceptions, so you don't have to depend on the WPF implementation. Something like:
public interface IFreezable
{
void Freeze();
bool IsFrozen { get; }
}
You can use the Lazy<T> class:
private readonly Lazy<Foo> _foo = new Lazy<Foo>(GetFoo);
public Foo Foo
{
get { return _foo.Value; }
}
private static Foo GetFoo()
{
// somehow create a Foo...
}
GetFoo will only be called the first time you call the Foo property.
This is know as the "once" feature in Eiffel. It is a major oversight in C#. The new Lazy type is a poor substitute since it is not interchangeable with its non-lazy version but instead requires you to access the contained value through its Value property. Consequently, I rarely use it. Noise is one of the biggest problems with C# code. Ideally, one wants something like this...
public once Type PropertyName { get { /* generate and return value */ } }
as oppose to the current best practice...
Type _PropertyName; //where type is a class or nullable structure
public Type PropertyName
{
get
{
if (_PropertyName == null)
_PropertyName = /* generate and return value */
return _PropertyName
}
}
Can somebody help me understand the get & set?
Why are they needed? I can just make a public variable.
Warning: I am assuming you already know about object-oriented programming.
What are properties?
Properties are language elements that allow you to avoid the repetitive getXYZ() accessors and setXYZ() mutators techniques found in other languages, like Java.
Why do they exist?
They aim to solve the following problems:
Saying get and set in the beginning of every access or mutation of a value is annoying and distracting.
In Java, you often say:
class person
{
private int _age;
public void setAge(int value) { /*check value first, then set _age*/ }
public int getAge() { return this._age; }
}
and then consistently say:
if (person.getAge() > blah || person.getAge() < 10)
{
person.setAge(5);
}
After a while, the get and set become rather annoying.
Providing direct access to the actual variable breaks encapsulation, so that's not an option.
How are they used?
They are used just like variables. You read/write to them just like variables.
How are they created?
They are created as methods. You define a pair of methods that:
Return the current value of the property. Oftentimes, this is nothing more than something like the following:
class Person
{
private int _age; //Declare the backing field
public int Age
{
get { return this._age; }
set { ... }
}
}
Set the value of the property:
class Person
{
public int Age
{
get { ... }
set
{
if (value < 0) //'value' is what the user provided
{ throw new ArgumentOutOfRangeException(); } //Check validity
this._age = value;
}
}
}
Other notes:
Auto-implemented Properties
C# 3.0 introduced auto-implemented properties:
public int Age { get; set; }
This is equivalent to:
private int _age; //The name is auto-generated
public int Age { get { return this._age; } set { this._age = value; } }
Why does it exist?
It helps you avoiding breaking changes in client executables.
Let's say you're lazy and don't want to type the whole thing, and decide to expose a variable publicly. You then create an executable that reads from or writes to that field. Then you change your mind and decide that you in fact needed a property, so you change it to one.
What happens?
The depending executable breaks, because the code is no longer valid.
Auto-implemented properties help you avoid that, without extra redundancy in your initial code.
Indexers
Indexers extend the property syntax to let you index objects (surprise!), just like arrays.
For C++ users: This is similar to overloading operator [].
Example:
private int[] _elements;
public int this[int index] //Indexed property
{
get { return this._elements[index]; }
set
{
//Do any checks on the index and value
this._elements[index] = value;
}
}
You then use them like obj[5] = 10;, which is equivalent to calling the set method of obj's indexer.
In fact, System.Collections.Generic.List<T> is indexed:
var list = new List<int>();
list.Add(10);
list[0] = 5; //You're indexing list, as though it were an array!
Isn't that neat? :)
Anything else?
There are many more features to properties, not all of which are available in C#:
Parametrized properties, of which indexers are a special kind
Getter/setter access modifiers (in C#)
Multiple getters or setters (not in C#)
Et cetera
They are called Accessors
The accessor of a property contains the executable statements associated with getting (reading or computing) or setting (writing) the property. The accessor declarations can contain a get accessor, a set accessor, or both.
The body of the get accessor resembles that of a method. It must return a value of the property type.
http://msdn.microsoft.com/en-us/library/w86s7x04.aspx
private string m_Name; // the name field
public string Name // the Name property
{
get
{
return m_Name;
}
}
The set accessor resembles a method whose return type is void. It uses an implicit parameter called value, whose type is the type of the property.
private m_Name;
public string Name {
get {
return m_Name;
}
set {
m_Name = value;
}
}
Then in the incarnation of C# 3, you can do this much easier through auto-properties
public string Name {get; set; } // read and write
public string Name {get; } // read only
public string Name { get; private set; } //read and parent write
http://msdn.microsoft.com/en-us/library/bb384054.aspx
Properties act as accessors to the internal state of an object, hiding the implementation of that state.
So, for example, you may have a first name property in a class
public class Example
{
private string firstName;
public string FirstName
{
get {return this.firstName;}
}
}
So anyone using the class doesn't need to know how first name is stored, they just know they can get a string representation of it. By adding a set you also add a mutator, something which changes an objects internal state
public class Example
{
private string firstName;
public string FirstName
{
get {return this.firstName;}
set {set this.firstName = value;}
}
}
Again you're still isolating how the first name is stored internally (encapsulation), but users can change it by passing in a string.
Simply put, get and set accessors are the functions called on a Property; that is, when you retrieve the value or when you set it. It forces a type of behavior on the way values are retrieved or set.
For example, you may want to have a mechanism to get/set passwords. Generally speaking, you'll only want to compare the hash of a password instead of storing things plaintext, so you'd have the getter variable retrieve the stored hash, and the setter would take the provided input and hash it for storage.
Here's what I mean:
public class User {
//Usery properties here, and...
private string _password;
public string Password {
get {
return _password;
}
set {
_password = SomeHashingFunction(value);
}
}
}
value is the variable provided to the setter from what has been given in the variable assignment. e.g.: someuser.Password = "blah";
Get and set are used in properties. They can each be public, protected, or private. Similar to accessor and mutator methods, they allow some computation when code tries to access/mutate the property. Of course, as long as you define one of get/set, the other is optional.
Example without properties:
private int test;
public int getTest() {
// some computation on test here, maybe?
return test;
}
private void setTest(int test) {
// some error/range checking, maybe?
this.test = test;
}
With properties:
private int test;
public int Test {
get {
// some computation on test here, maybe?
return test;
}
private set {
// some error/range checking, maybe?
test = value; // value is a keyword here
}
}
get{} and set{} are accessors that offer up the ability to easily read and write to private fields. Working with a simple example:
public class Foo()
{
//Field
private int _bar;
//Property
public int Bar
{
get { return _bar; }
set { _bar = value; }
//value is an implicit parameter to the set acccessor.
//When you perform an assignment to the property, the value you
//assign is the value in "value"
}
}
In this case, Bar is a public property that has a getter and a setter that allows access to the private field _bar that would otherwise be inaccessible beyond class Foo.
Now in a class that has an instace of Foo, you can do this:
public class IHasAFoo()
{
private Foo _myFoo = new Foo();
public void SomeMethod()
{
_myFoo.Bar = 42;
}
}
So the public accessor allows you to set the value of the private field back in Foo.
Hope that helps!
How can I implement a CacheAttribute so I can have the same logic for all properties in one place?
I am doing this to cache
[TestClass]
public class All
{
public string N
{
get
{
var value =
MemoryCache.Default.Get("Website.Tests.All.N") as string;
if (value != null)
{
return value;
}
value = DateTime.Now.ToString("HH:mm:ss.ffff");
MemoryCache.Default.Add("Website.Tests.All.N", value,
new CacheItemPolicy
{
AbsoluteExpiration =
new DateTimeOffset(DateTime.Now.AddSeconds(5))
});
return value;
}
}
[TestMethod]
public void Extension()
{
var start = N;
Thread.Sleep(1000);
var end = N;
Assert.AreEqual(start, end);
}
}
And I want to use this instead
[TestClass]
public class All
{
[Cache(Duration=5000)]
public string N
{
get
{
return DateTime.Now.ToString("HH:mm:ss.ffff");
}
}
[TestMethod]
public void Extension()
{
var start = N;
Thread.Sleep(1000);
var end = N;
Assert.AreEqual(start, end);
}
}
Is there a way to make this syntax sugar?
It seems you want to "take over" the get method for the property so as to inspect a cache first before returning the "actual" value from your property. Since there is no way to perform property interception on an ad-hoc basis, you'll have to plan ahead for this facility.
One approach would be to use interfaces and write your classes to the interface. For example,
public interface IAll
{
string N { get; set; }
}
Now you can use proxies to create a wrapper around the original instance of All that also implements this interface. Furthermore, since you're fully in charge of the property now, you can check the cache whenever the getter is called. Since you'll have the PropertyInfo/MethodInfo at your disposal, you should have no trouble generating a unique key per property.
So, whenever you would instantiate an instance of All, you also instantiate this proxy, passing it the instance of All. All subsequent usages of that instance of All should instead be passed the proxy. Like any class factory implementation, this requires you to forgo use of the new operator.
Alternatively, you can use virtual methods instead of interfaces.