I have a class as follows:
class Foo : PropertyChangedBase {
private int _property;
public int Property {
get { return _property; }
set { OnAssignPropertyChanged("Property", () => _property, value); }
}
PropertyChangedBase implements INotifyPropertyChanged with the following methods:
protected void OnAssignmentPropertyChanged<T>(string propertyName, Expression<Func<T>> fieldExpression, T value)
{
var get = fieldExpression.Compile();
if (get().Equals(value))
{
return;
}
// invoke set property method
SetProperty(fieldExpression, value);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void SetProperty<T>(Expression<Func<T>> fieldExpression, T value)
{
if (fieldExpression == null)
{
throw new ArgumentNullException(nameof(fieldExpression));
}
var memberExpression = fieldExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("fieldExpression");
}
var field = memberExpression.Member as FieldInfo;
if (field == null)
{
throw new ArgumentException("fieldExpression");
}
field.SetValue(this, value);
}
I would prefer to call:
OnAssignPropertyChanged(() => Property, value);
The only way this will work is if I can get the backing field for the property getter and then pass that to SetProperty. Is it possible to get the FieldInfo or target member from the property get method?
As a general answer, yes you can do, at least under controlled conditions. But the only case you should do this is when you are absoluty sure what you are doing and only with limited support, because there will be cases you can not handle.
Have a look at the answer here: Find all property references using reflection. The target is a bit different but the approach is similar for finding field references. Since the answer there already includes the necessary code i will just outline the way to go:
All metadata items in .Net are referenced by tokens. To get tokens used inside a method you have to parse the MethodBody (by skipping all the things you wont inspect) and then resolve the found tokens in their module. Remember to use the BitConverter when reading the tokens from the stream to resolve them.
But now to the down side; the only time you can really safely use this to find the backing fields of a properties getter, is when you find a simple get method, with a well defined opcode sequence like Ldfld, Ret or something like that. Maybe you can define a few patterns that the C# compiler will emit for simple and autoimplemented properties. If you find anything different there is no other way as to resign and throw an exception, because the getter could contain any code.
Like always with reflection, only use whitelist approaches, check for the conditions you expect and throw exeptions in any other case or you will run into a NullReferenceException sooner or later.
If this is worth the trouble is for you to decide, but in general you could do this since .Net 2.0 and do not even need a fancy external lib.
No, in general case you can't. Just compare two classes:
public class Test {
private int _propA;
private int _propB;
public int PropA {get { return _propA; }}
public int PropB {get { return _propB; }}
}
public class TestSwapped {
private int _propA;
private int _propB;
// please, notice swapped backing fields
public int PropA {get { return _propB; }}
public int PropB {get { return _propA; }}
}
you'll get identical PropertyInfo[] and FieldInfo[] arrays but different backing fields
In pursuing this for a different question, here is an extension method for the simple cases - an autogenerated backing field, or a get that just returns a backing field:
public static class MethodInfoExt {
const int IL_ldarg0 = 0x02;
const int IL_ldfld = 0x7B;
public static FieldInfo FieldInfoFromGetAccessor(this MethodInfo getAccessorMI) {
var body = getAccessorMI.GetMethodBody().GetILAsByteArray();
if (body[0] == IL_ldarg0 && body[1] == IL_ldfld) {
var fieldToken = BitConverter.ToInt32(body, 2);
return getAccessorMI.DeclaringType.Module.ResolveField(fieldToken);
}
else
return default;
}
}
You can not. Property can have no backing fields or sets of backing fields.
Even set property can have no backing fields at all.
public Int32 Prop
{
set { Debug.WriteLine(value.ToString()); }
get { return 1; }
}
What are you expecting to get in FieldInfo?
Property is just a syntax sugar for a pair of set/get methods, or mutators. Being a method allows them to contain as much code as needed, including being just empty and, of course, there is no requirement to have a backing field from compiler perspective.
Related
I have a property which getter should load its value only the first time. The second time it returns the loaded value without loading it again:
private Object _MemberValue;
public Object MemberValue
{
get
{
if(_MemberValue == null)
{
_MemberValue = LoadMember();
}
return _MemberValue;
}
}
In VB.NET there is the Static keyword. With it you don't have to declare a class wide member.
Public Property MemberValue as Object
Get
Static value as Object = Nothing
If (value is Nothing) Then
value = LoadMember()
End If
Return value
End Get
End Property
In C# there isn't such a keyword.
Are there better C# implementations of this problem or other patterns?
Are there better C# implementations of this problem or other patterns?
Probably not. You can use Lazy<T> as an replacement if you like, but basically it is the same as your first example. Using Static in VB.NET has some serious drawbacks, so I wouldn't use it either way.
If you prefer Lazy<T>, this is what I would use:
private Lazy<object> _MemberLazy = new Lazy<object>(LoadMember);
public object MemberValue
{
get
{
return _MemberLazy.Value;
}
}
Your initial approach seems appropriate, I have never had reason to do something different. That said if your goal here is to avoid a class level field that could potentially be written to outside the getter, perhaps something like this would work. There are a number of other ReadOnly, WriteOnce, SetOnce implementations that would also work similarly.
ReadOnlyField.cs
public class ReadOnlyField<T>
{
private bool _frozen;
private T _value;
public T Value
{
get { return _value; }
set
{
if (_frozen)
throw new InvalidOperationException();
_value = value;
}
}
public void Freeze()
{
_frozen = true;
}
}
YourObject.cs
public class YourObject
{
private readonly ReadOnlyField<object> _someMember;
public object MemberValue
{
get
{
if(_someMember.Value == null)
{
_someMember.Value = LoadMember();
_someMember.Freeze();
}
return _someMember.Value;
}
}
public YourObject()
{
_someMember = new ReadOnlyField<object>();
}
}
It's not perfect. Unlike your VB.Net example; code outside of the getter could write to the field first, but at least you're protected from it being overwritten after Freeze is called.
For an object sellprint declared as static in the class
private static string sellprint = "";
public string Sellprint
{
get { return sellprint; }
}
public void SetSellprint(string x)
{
sellprint = x;
}
How is this
different from
public string Sellprint
{
get; set;
}
internally.
I could not find any examples of code 1 on msdn. what does it translate into?
The compiler creates a getter method for your property in the first code that returns the value of sellprint field because you implement only the getter method.In the second code, both getter and setter methods creating by compiler and also the backing-field.That's the difference.
You can verify that using ILDASM.exe:
First, consider this code:
class Foo
{
private string _value;
public string Value
{
get { return _value; }
}
public void SetValue(string str)
{
_value = str;
}
}
As you can see there is only one method generated by compiler which is get_Value.
If we change it like this and make the Value an auto-implemented property:
class Foo
{
public string Value { get; set; }
}
You can see that compiler creates both getter (get_Value) and setter (set_Value) method and also create a private backing field for the property.
There is no pros or cons about the functionality except in the second code you are doing the same work with less code.
1) should not work because there is no sellprint - assuming you have a field named sellprint and just forgot in your code snippet, you provide a get accessors and a method instead of the set accessors, which is kinda strange.
2) will create the field required automatically (and will not tell you the name, so you cannot accidentally use it)
There is not difference between those two though.
When .NET 4.5 was released i started using such great Attribute as CallerMemberName. It's easier to understand code, developers can write it faster also. It's like a snippet, not only a feature for debug/test purposes.
So I have a question. Is it normal to create and use something like this?
public class PropertyStore
{
Dictionary<string, object> data = new Dictionary<string,object>();
ViewModelBase modelBase;
internal PropertyStore(ViewModelBase _base)
{
modelBase = _base;
}
public void SetValue<T>(T value = default(T), [CallerMemberName] string prop = "")
{
T prev = GetValue<T>(prop);
if ((prev == null && value == null) || (prev != null && prev.Equals(value))) return;
data[prop] = value;
modelBase.OnPropertyChanged(prop);
}
public T GetValue<T>([CallerMemberName] string prop = "")
{
if (!data.ContainsKey(prop))
data[prop] = default(T);
return (T)data[prop];
}
}
Class-helper, that makes other class more readable, and also we have list of our properties without need to use Reflection.
The usage is:
public class SampleClass : ViewModelBase
{
PropertyStore PropertyStore;
public SampleClass ()
{
PropertyStore = new PropertyStore(this);
}
public string Key
{
get { return PropertyStore.GetValue<string>(); }
set { PropertyStore.SetValue(value); }
}
public DateTime Date
{
get { return PropertyStore.GetValue<DateTime>(); }
set { PropertyStore.SetValue(value); }
}
public bool IsSelected
{
get { return PropertyStore.GetValue<bool>(); }
set { PropertyStore.SetValue(value); }
}
}
The class ViewModelBase here simply implements INotifyPropertyChanged interface.
As I understand, this approach is something like Microsoft Dependency Properties, but I don't need all power of DependencyObject class, and I don't want inherit it.
With something like this I can use Binding, because it's enough to implement INotifyPropertyChanged, also we have no fields (as for me, i try to use properties smarter, than using fields directly (however, there is no problem to use Dictionary directly ^_^))
Sorry for my bad English... Not main language and not much practice.
Another Sample (after moving Methods to base class)
public class SampleClass : ViewModelBase
{
public string Key
{
get { return GetValue<string>(); }
set { SetValue(value); }
}
public DateTime Date
{
get { return GetValue<DateTime>(); }
set { SetValue(value); }
}
public bool IsSelected
{
get { return GetValue<bool>(); }
set { SetValue(value); }
}
}
No diff with Microsoft's WPF Property System.
Only feature you'll get with it is an ability to access property values via Dictionary.Get|Set methods.
You can get this ability with field based implementation of INotifyPropertyChanged. You can access property values by its name using dictionary, with property name to precompiled delegate mapping like it done in Yappi project.
var dateValue= Property<SampleClass>.Get<DateTime>(this,"Date");
Property<SampleClass>.Set<DateTime>(this,"Date",DateTime.Now);
Both can be rewritten as extension methods.
Nice idea, property bag without reflection and it will even work with obfuscation.
I don't see major problems with it but you may consider the following:
The prop parameter is optional so potentially a bug can be introduced by given a value in the call.
Value types will get boxed.
Access to the fields is relatively more expensive, can be a factor more expensive as you have much more code in a simple get (especially with boxing).
Dictionary takes more space than the number of properties you keep in (especially with boxing).
Each property also stores a string of the property name adding to the overhead.
I have created the following class based on a Singleton Pattern:
public sealed class UTrans
{
private static volatile UTrans _instance;
private static readonly object syncRoot = new Object();
private UTrans(){}
private static UTrans Instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
if (_instance == null)
_instance = new UTrans();
}
}
return _instance;
}
}
}
Within this Class I have created an enum property and string property
private static MethodType _method; // Alphabectic 1 - 50
public static MethodType Method
{
get { return _method; }
set { _method = value; }
}
private static string _uName;
public static string UserName
{
get { return _uName; }
set { _uName = value; }
}
I also have some methods that take a number of arguments in this class. When I call the class instance in code, if the user assigns values to the properties; those values will be used. Otherwise, the values passed as arguments will be used.
This works fine in the case of the UserName property by checking for a null value on the property:
var un = UserName ?? user;
However I cannot perform the same check for the enumeration property because it seems that the property automatically assumes the 1st value of the enumeration if one is not assigned.
I tried to circumvent the issue by assigning the 1st value of the enum as "Unspecified". Then I may proceed to code as such:
var processMethod = TranslateMethodType(Method) == "Unspecified" ? method : Method;
Where TranslateMethodType is a private method that converts the selected enumeration to a equivalent string value.
I don't believe this is the most elegant approach to the issue though and would like some feedback on possible alternatives to this issue.
Is there a way to check that a value has not been set for the MethodType property by the user of the class without having to add an "Unspecified" value as the first value since this value is ONLY there as a way to indicate no value was set?
Obviously, this may not be the case if the user decides to use the value and it would yield undesirable results to construct the code this way.
Can a enumeration Method be marked as nullable???
Can a enumeration Method be marked as nullable???
Yes.
public Nullable<MyEnum> Bob(){
//stuff
}
var bob = Bob() ?? MyEnum.Default;
Yes, you can make the Method field/property nullable.
private static MethodType? _method; // Alphabectic 1 - 50
public static MethodType? Method
{
get { return _method; }
set { _method = value; }
}
Then you can do
var processMethod = Method == null ? method : Method.Value;
or
var processMethod = Method.HasValue ? Method.Value: method;
You can mark it as nullable however what you're experiencing is expected behaviour.
Value types that are members of a reference type are initialized to 0. This is why you should always provide a value of 0 for your enums. If you don't, then users of your class will never know that the class has invalid state.
I have some extension methods which could be used like this:
MyType myObject;
string displayName = myObject.GetDisplayName(x => x.Property);
The problem here is that it needs an instance, even if the extension method only needs the type MyType. So if there is no instance, it needs to be called like this:
string displayName = BlahBlahUtility.GetDisplayName((MyTpe x) => x.Property);
Which is not so nice anymore.
Is there a way to write better syntax for such cases?
What I actually want to do is this (pseudo language):
string displayName = MyType.Property.GetDisplayName()
Which of course does not work with C#.
But what about something like this:
string displayName = ((MyType x) => x.Property).GetDisplayName();
This is also not possible (after a lambda, a dot is not accepted).
Any ideas?
Edit:
My "favorite syntax" MyType.Property.GetDisplayName() seems to be misleading. I don't talk about static properties here. I know that this syntax won't be possible. I just tried to show in pseudo language, what information is necessary. This would be ideal, every additional stuff is just syntactical overhead. Any working syntax that is close to this would be great.
I don't want to write a certain extension method. I want an easy, readable and compile time safe syntax, using any language feature.
Have a look at the Express and Reflect classes in the Lokad Shared Libraries. Think they may help out with what you are trying to do. Read more here:
Strongly Typed Reflection in Lokad Shared
How to Find Out Variable or Parameter Name in C#?
From your comment: "I want an easy and compile time safe syntax to get information about members".
This is a very frequently requested feature and has been discussed in the C# team's meetings for about a decade, but has never been prioritised high enough to be included.
This blog post explains why:
http://blogs.msdn.com/ericlippert/archive/2009/05/21/in-foof-we-trust-a-dialogue.aspx
So for now, you're just going to be fighting against a missing feature. Maybe you could post more information about your broader problem and see if people can suggest different approaches.
Update
Without more info about your problem this is just guesswork. But if you have a property that represents a value but also carries additional "meta" information, you could always represent that as a new type and use an "injection" step to set everything up.
Here's a suggested abstract interface to such a "meta property":
public interface IMetaProperty<TValue>
{
TValue Value { get; set; }
string DisplayName { get; }
event Action<TValue, TValue> ValueChanged;
}
The value of the property is just another sub-property, with its type defined by the user.
I've put in the display name, and also as a bonus you've got an event that fires when the value changes (so you get "observability" for free).
To have properties like this in a class, you'd declare it like this:
public class SomeClass
{
public IMetaProperty<string> FirstName { get; private set; }
public IMetaProperty<string> LastName { get; private set; }
public IMetaProperty<int> Age { get; private set; }
public SomeClass() { MetaProperty.Inject(this); }
}
Note how the setters on the properties are private. This stops anyone from accidentally setting the property itself instead of setting the Value sub-property.
So this means the class has to set up those properties so they aren't just null. It does this by calling a magic Inject method, which can work on any class:
public static class MetaProperty
{
// Make it convenient for us to fill in the meta information
private interface IMetaPropertyInit
{
string DisplayName { get; set; }
}
// Implementation of a meta-property
private class MetaPropertyImpl<TValue> : IMetaProperty<TValue>,
IMetaPropertyInit
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
var old = _value;
_value = value;
ValueChanged(old, _value);
}
}
public string DisplayName { get; set; }
public event Action<TValue, TValue> ValueChanged = delegate { };
}
public static void Inject(object target)
{
// for each meta property...
foreach (var property in target.GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition()
== typeof(IMetaProperty<>)))
{
// construct an implementation with the correct type
var impl = (IMetaPropertyInit)
typeof (MetaPropertyImpl<>).MakeGenericType(
property.PropertyType.GetGenericArguments()
).GetConstructor(Type.EmptyTypes).Invoke(null);
// initialize any meta info (could examine attributes...)
impl.DisplayName = property.Name;
// set the value
property.SetValue(target, impl, null);
}
}
}
It just uses reflection to find all the IMetaProperty slots hiding in the object, and fills them in with an implementation.
So now a user of SomeClass could say:
var sc = new SomeClass
{
FirstName = { Value = "Homer" },
LastName = { Value = "Simpson" },
Age = { Value = 38 },
};
Console.WriteLine(sc.FirstName.DisplayName + " = " + sc.FirstName.Value);
sc.Age.ValueChanged += (from, to) =>
Console.WriteLine("Age changed from " + from + " to " + to);
sc.Age.Value = 39;
// sc.Age = null; compiler would stop this
If you're already using an IOC container you may be able to achieve some of this without going directly to reflection.
It looks like you're trying to create a static extension method?
DateTime yesterday = DateTime.Yesterday(); // Static extension.
Instead of
DateTime yesterday = DateTime.Now.Yesterday(); // Extension on DateTime instance.
If this is what you're trying to pull off, I do not believe it is possible in the current version of C#.
It sounds like you are integrating layers a little too tightly. Normally in this type of situation I would let the presentation layer decide the implementation of GetDisplayName() instead of making it an extension of the property itself. You could create an interface called MyTypeDisplayer or whatever you fancy, and let there be multiple implementations of it not limiting you to a single display implementation.
The issue here is that one cannot get a reference to non-static methods via instance MyType.[Member]. These can only be seen through a reference to an instance of the type. You also cannot build an extension method on-top of a type declaration, only on an instance of a type - that is the extension method itself has to be defined using an instance of a type (this T x).
One can however define the expression like this to get a reference to static members:
((MyType x) => MyType.Property)
One could do something similar to string displayName = ((MyType x) => x.Property).GetDisplayName();
The first issue is guaranteeing that the compiler treats your (x=> x.Property) as an Expression rather than an action/func etc...
To do this one might need to do this:
string displayName = ((Expression<Func<PropertyType>>)((MyType x) => x.Property).GetDisplayName();
The extension method would then have to be defined like this:
public static string GetDisplayName<T>(this Expression<Func<T>> expression)
You might also have to define an extension method on top of Expression<Action>> and Expression<Action<T>> if your members are also methods.
You can do a dot after an Expression - this is where the Compile method would reside.
Appended:
I think the static call to the extension method in cases that one doesn't have an instance of the type one needs to do "reflection" on to determine a Members name would be the cleanest syntax still - this way you could still use the extension method when using an instance of a type and fall back to the static call definition => MyExtensionClass.GetDisplayName(TypeOfX x => TypeOfX.StaticMember OR x.Property/Member) when one doesn't have an instance
If you interface your properties, you could make the extension on the interface instead:
namespace Linq1
{
class Program
{
static void Main(string[] args)
{
MyType o = new MyType();
o.Property.GetDisplayName();
}
}
public class MyType
{
public IDisplayableProperty Property { get; set; }
}
public interface IDisplayableProperty
{
string GetText();
}
public class MyProperty1 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public class MyProperty2 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public static class Extensions
{
public static string GetDisplayName(this IDisplayableProperty o)
{
return o.GetText();
}
}
}