Access property by Index - c#

I need to access a property by an index or something similar. The reason why is explained in this already answered question. That answer uses Linq and I prefer something without that dependency. I have no control over the class.
public class myClass
{
private string s = "some string";
public string S
{
get { return s; }
}
}
class Program
{
static void Main(string[] args)
{
myClass c = new myClass();
// I would like something similar
// or same functionality
string s = c["S"];
}
}

As you have no control over the class you can use extension method and reflection to get property value by name:
static class ObjectExtensions
{
public static TResult Get<TResult>(this object #this, string propertyName)
{
return (TResult)#this.GetType().GetProperty(propertyName).GetValue(#this, null);
}
}
Usage:
class A
{
public string Z
{
get;
set;
}
public int X
{
get;
set;
}
}
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.Z = "aaa";
obj.X = 15;
Console.WriteLine(obj.Get<string>("Z"));
Console.WriteLine(obj.Get<int>("X"));
Console.ReadLine();
}
}

use (EDIT - as per comment):
string s = c.GetType().GetProperty ("S").GetGetMethod().Invoke (c, null).ToString();
It gives you the value of the (public) property named S of the the instance c regardless of the type of c and doesn't use LINQ at all although I must admit that I don't see why LINQ should be a problem...

You can achieve the same thing by using a default property on your class and a collection. Provided that you will always want strings, you could use the Dictionary class as your default property.
Then in the constructor you could intialize myDictionary["s"] = "some string";
You could then use the myClass as a collection, so myClass["s"] would return "some string".
Reflection is usually an indicator that you haven't created an API to do the job you need, if you have the code to modify then I recommend you use the default property.
See this MSDN article:

Related

Instance { get; } = new <class>() - Is this a C#7/8/9 feature? [duplicate]

How do you give a C# auto-property an initial value?
I either use the constructor, or revert to the old syntax.
Using the Constructor:
class Person
{
public Person()
{
Name = "Initial Name";
}
public string Name { get; set; }
}
Using normal property syntax (with an initial value)
private string name = "Initial Name";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Is there a better way?
In C# 5 and earlier, to give auto implemented properties an initial value, you have to do it in a constructor.
Since C# 6.0, you can specify initial value in-line. The syntax is:
public int X { get; set; } = x; // C# 6 or higher
DefaultValueAttribute is intended to be used by the VS designer (or any other consumer) to specify a default value, not an initial value. (Even if in designed object, initial value is the default value).
At compile time DefaultValueAttribute will not impact the generated IL and it will not be read to initialize the property to that value (see DefaultValue attribute is not working with my Auto Property).
Example of attributes that impact the IL are ThreadStaticAttribute, CallerMemberNameAttribute, ...
Edited on 1/2/15
C# 6 :
With C# 6 you can initialize auto-properties directly (finally!), there are now other answers that describe that.
C# 5 and below:
Though the intended use of the attribute is not to actually set the values of the properties, you can use reflection to always set them anyway...
public class DefaultValuesTest
{
public DefaultValuesTest()
{
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
{
DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
if (myAttribute != null)
{
property.SetValue(this, myAttribute.Value);
}
}
}
public void DoTest()
{
var db = DefaultValueBool;
var ds = DefaultValueString;
var di = DefaultValueInt;
}
[System.ComponentModel.DefaultValue(true)]
public bool DefaultValueBool { get; set; }
[System.ComponentModel.DefaultValue("Good")]
public string DefaultValueString { get; set; }
[System.ComponentModel.DefaultValue(27)]
public int DefaultValueInt { get; set; }
}
When you inline an initial value for a variable it will be done implicitly in the constructor anyway.
I would argue that this syntax was best practice in C# up to 5:
class Person
{
public Person()
{
//do anything before variable assignment
//assign initial values
Name = "Default Name";
//do anything after variable assignment
}
public string Name { get; set; }
}
As this gives you clear control of the order values are assigned.
As of C#6 there is a new way:
public string Name { get; set; } = "Default Name";
Sometimes I use this, if I don't want it to be actually set and persisted in my db:
class Person
{
private string _name;
public string Name
{
get
{
return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
}
set { _name = value; }
}
}
Obviously if it's not a string then I might make the object nullable ( double?, int? ) and check if it's null, return a default, or return the value it's set to.
Then I can make a check in my repository to see if it's my default and not persist, or make a backdoor check in to see the true status of the backing value, before saving.
In C# 6.0 this is a breeze!
You can do it in the Class declaration itself, in the property declaration statements.
public class Coordinate
{
public int X { get; set; } = 34; // get or set auto-property with initializer
public int Y { get; } = 89; // read-only auto-property with initializer
public int Z { get; } // read-only auto-property with no initializer
// so it has to be initialized from constructor
public Coordinate() // .ctor()
{
Z = 42;
}
}
Starting with C# 6.0, We can assign default value to auto-implemented properties.
public string Name { get; set; } = "Some Name";
We can also create read-only auto implemented property like:
public string Name { get; } = "Some Name";
See: C# 6: First reactions , Initializers for automatically implemented properties - By Jon Skeet
In Version of C# (6.0) & greater, you can do :
For Readonly properties
public int ReadOnlyProp => 2;
For both Writable & Readable properties
public string PropTest { get; set; } = "test";
In current Version of C# (7.0), you can do : (The snippet rather displays how you can use expression bodied get/set accessors to make is more compact when using with backing fields)
private string label = "Default Value";
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value;
}
In C# 9.0 was added support of init keyword - very useful and extremly sophisticated way for declaration read-only auto-properties:
Declare:
class Person
{
public string Name { get; init; } = "Anonymous user";
}
~Enjoy~ Use:
// 1. Person with default name
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
// > Hello, Anonymous user!
// 2. Person with assigned value
var me = new Person { Name = "#codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// > Hello, #codez0mb1e!
// 3. Attempt to re-assignment Name
me.Name = "My fake";
// > Compilation error: Init-only property can only be assigned in an object initializer
In addition to the answer already accepted, for the scenario when you want to define a default property as a function of other properties you can use expression body notation on C#6.0 (and higher) for even more elegant and concise constructs like:
public class Person{
public string FullName => $"{First} {Last}"; // expression body notation
public string First { get; set; } = "First";
public string Last { get; set; } = "Last";
}
You can use the above in the following fashion
var p = new Person();
p.FullName; // First Last
p.First = "Jon";
p.Last = "Snow";
p.FullName; // Jon Snow
In order to be able to use the above "=>" notation, the property must be read only, and you do not use the get accessor keyword.
Details on MSDN
In C# 6 and above you can simply use the syntax:
public object Foo { get; set; } = bar;
Note that to have a readonly property simply omit the set, as so:
public object Foo { get; } = bar;
You can also assign readonly auto-properties from the constructor.
Prior to this I responded as below.
I'd avoid adding a default to the constructor; leave that for dynamic assignments and avoid having two points at which the variable is assigned (i.e. the type default and in the constructor). Typically I'd simply write a normal property in such cases.
One other option is to do what ASP.Net does and define defaults via an attribute:
http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
My solution is to use a custom attribute that provides default value property initialization by constant or using property type initializer.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InstanceAttribute : Attribute
{
public bool IsConstructorCall { get; private set; }
public object[] Values { get; private set; }
public InstanceAttribute() : this(true) { }
public InstanceAttribute(object value) : this(false, value) { }
public InstanceAttribute(bool isConstructorCall, params object[] values)
{
IsConstructorCall = isConstructorCall;
Values = values ?? new object[0];
}
}
To use this attribute it's necessary to inherit a class from special base class-initializer or use a static helper method:
public abstract class DefaultValueInitializer
{
protected DefaultValueInitializer()
{
InitializeDefaultValues(this);
}
public static void InitializeDefaultValues(object obj)
{
var props = from prop in obj.GetType().GetProperties()
let attrs = prop.GetCustomAttributes(typeof(InstanceAttribute), false)
where attrs.Any()
select new { Property = prop, Attr = ((InstanceAttribute)attrs.First()) };
foreach (var pair in props)
{
object value = !pair.Attr.IsConstructorCall && pair.Attr.Values.Length > 0
? pair.Attr.Values[0]
: Activator.CreateInstance(pair.Property.PropertyType, pair.Attr.Values);
pair.Property.SetValue(obj, value, null);
}
}
}
Usage example:
public class Simple : DefaultValueInitializer
{
[Instance("StringValue")]
public string StringValue { get; set; }
[Instance]
public List<string> Items { get; set; }
[Instance(true, 3,4)]
public Point Point { get; set; }
}
public static void Main(string[] args)
{
var obj = new Simple
{
Items = {"Item1"}
};
Console.WriteLine(obj.Items[0]);
Console.WriteLine(obj.Point);
Console.WriteLine(obj.StringValue);
}
Output:
Item1
(X=3,Y=4)
StringValue
little complete sample:
using System.ComponentModel;
private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
get { return bShowGroup; }
set { bShowGroup = value; }
}
You can simple put like this
public sealed class Employee
{
public int Id { get; set; } = 101;
}
In the constructor. The constructor's purpose is to initialized it's data members.
private string name;
public string Name
{
get
{
if(name == null)
{
name = "Default Name";
}
return name;
}
set
{
name = value;
}
}
Have you tried using the DefaultValueAttribute or ShouldSerialize and Reset methods in conjunction with the constructor? I feel like one of these two methods is necessary if you're making a class that might show up on the designer surface or in a property grid.
Use the constructor because "When the constructor is finished, Construction should be finished". properties are like states your classes hold, if you had to initialize a default state, you would do that in your constructor.
To clarify, yes, you need to set default values in the constructor for class derived objects. You will need to ensure the constructor exists with the proper access modifier for construction where used. If the object is not instantiated, e.g. it has no constructor (e.g. static methods) then the default value can be set by the field. The reasoning here is that the object itself will be created only once and you do not instantiate it.
#Darren Kopp - good answer, clean, and correct. And to reiterate, you CAN write constructors for Abstract methods. You just need to access them from the base class when writing the constructor:
Constructor at Base Class:
public BaseClassAbstract()
{
this.PropertyName = "Default Name";
}
Constructor at Derived / Concrete / Sub-Class:
public SubClass() : base() { }
The point here is that the instance variable drawn from the base class may bury your base field name. Setting the current instantiated object value using "this." will allow you to correctly form your object with respect to the current instance and required permission levels (access modifiers) where you are instantiating it.
public Class ClassName{
public int PropName{get;set;}
public ClassName{
PropName=0; //Default Value
}
}
This is old now, and my position has changed. I'm leaving the original answer for posterity only.
Personally, I don't see the point of making it a property at all if you're not going to do anything at all beyond the auto-property. Just leave it as a field. The encapsulation benefit for these item are just red herrings, because there's nothing behind them to encapsulate. If you ever need to change the underlying implementation you're still free to refactor them as properties without breaking any dependent code.
Hmm... maybe this will be the subject of it's own question later
class Person
{
/// Gets/sets a value indicating whether auto
/// save of review layer is enabled or not
[System.ComponentModel.DefaultValue(true)]
public bool AutoSaveReviewLayer { get; set; }
}
I know this is an old question, but it came up when I was looking for how to have a default value that gets inherited with the option to override, I came up with
//base class
public class Car
{
public virtual string FuelUnits
{
get { return "gasoline in gallons"; }
protected set { }
}
}
//derived
public class Tesla : Car
{
public override string FuelUnits => "ampere hour";
}
I think this would do it for ya givng SomeFlag a default of false.
private bool _SomeFlagSet = false;
public bool SomeFlag
{
get
{
if (!_SomeFlagSet)
SomeFlag = false;
return SomeFlag;
}
set
{
if (!_SomeFlagSet)
_SomeFlagSet = true;
SomeFlag = value;
}
}

Creating a non-static version of compiler-based "dictionary" where keys are types

There is a very easy trick which creates a dictionary-like structure where keys are types.
The structure acts like a Dictionary<Type, T?> where keys are Type objects and values are instances of the corresponding types.
This wonderful structure is as fast as just a variable or array since the "lookup" is only done once by the compiler/JITter and the proper value reference is compiled into your program.
public static class MyDict<T> {
public static T Value { get; set; }
}
You can work with that structure like this:
MyDict<string>.Value = MyDict<int>.Value.ToString();
The problem is that this "dictionary" is global. The only way to create different dictionaries is to create different classes.
How can create a similar (fastest "lookup", no boxing) non-static structure? (Without code generation.)
Simply said: I want to have multiple Dictionary<Type, object>-like objects without lookup costs, casting and boxing.
Here's an approach that extends the method described in the question:
public class TypeDict
{
public T Get<T>()
{
return MyDict<T>.Values[this];
}
public void Set<T>(T value)
{
MyDict<T>.Values[this] = value;
}
private static class MyDict<T>
{
public static Dictionary<TypeDict, T> Values { get; private set; }
static MyDict()
{
Values = new Dictionary<TypeDict, T>();
}
}
}
Now we can use the TypeDict like this:
void X()
{
var a = new TypeDict();
var b = new TypeDict();
a.Set<int>(1);
a.Set<double>(3.14);
a.Set("Hello, world!");
//Note that type inference allows us to omit the type argument
b.Set(10);
b.Set(31.4);
b.Set("Hello, world, times ten!");
Console.WriteLine(a.Get<int>());
Console.WriteLine(a.Get<double>());
Console.WriteLine(a.Get<string>());
Console.WriteLine();
Console.WriteLine(b.Get<int>());
Console.WriteLine(b.Get<double>());
Console.WriteLine(b.Get<string>());
}
Ark-kun is using generics to essentially generate unique types at compile time. With a generic type, any static members are unique to that specific closed generic type. This way it's processed as fast as a standard static member lookup.
The above usage is equivalent to something like this:
public static class MyDict_String
{
public static string Value { get; set; }
}
public static class MyDict_Int32
{
public static int Value { get; set; }
}
MyDict_String.Value = MyDict_Int32.Value.ToString();
AFAIK, types are "static" (in that you can't define more than one that way) so I don't know of a way to cheat around this and maintain the same performance of a statically compiled member lookup.
Your best bet otherwise (I think) is to create a generic instance type that wraps its own dictionary that uses System.Type for its keys and System.Object for its values to which you have to perform boxing/casting when inserting/retrieving values.
EDIT: Here's a simple implementation wrapping a dictionary:
public class MyTypedDict
{
private Dictionary<Type, object> Values = new Dictionary<Type, object>();
public T Get<T>()
{
object untypedValue;
if (Values.TryGetValue(typeof(T), out untypedValue))
return (T)untypedValue;
return default(T);
}
public void Set<T>(T value)
{
Values[typeof(T)] = value;
}
}
Thinking about it more, it might be possible to achieve a more property-like syntax using an ExpandoObject (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) through some tomfoolery, but I feel like this would be pretty abusive and I can only assume terribly prone to runtime errors. (plus it would afford you nothing at compile time)
EDITx2: If you really want to have different sets of values, you could nest it within another generic type:
public static class ValueSets<T>
{
public static class MyDict<U>
{
public static U Value { get; set; }
}
}
With usage like:
ValueSets<int>.MyDict<string>.Value = "Hello ";
ValueSets<bool>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<int>.MyDict<string>.Value + ValueSets<bool>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
But then the initial type int and bool in this case become "magical" and without meaning, plus you would need to provide a unique type per distinct set of values you'd like to use. Plus you could not pass it around and modify as an instance variable, rather it'd be statically accessible (so long as you have access to use the type T). So perhaps you could declare minimally visible types that are named with meaning and use those:
internal class MyFirstWords {}
internal class MySecondWords {}
ValueSets<MyFirstWords>.MyDict<string>.Value = "Hello ";
ValueSets<MySecondWords>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<MyFirstWords>.MyDict<string>.Value + ValueSets<MySecondWords>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
Regardless, I think this is quite wacky and I wouldn't recommend it.
A more complicated version. Don't know if it's closer:
Define a generic dictionary:
public class MyDictionary<T>
{
Dictionary<string, T> dict;
public MyDictionary()
{
dict = new Dictionary<string, T>();
}
public T this[string name]
{
get
{
if (dict.ContainsKey(name))
return dict[name];
else
return default(T);//or throw
}
set
{
dict[name] = value;
}
}
}
Then a repository to store those dictionaries:
public class MyRepository
{
List<object> repo;
public MyRepository()
{
repo = new List<object>();
}
public void Add<T>(string name, T value)
{
if (!repo.OfType<MyDictionary<T>>().Any())
repo.Add(new MyDictionary<T>());
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
dict[name] = value;
}
public T GetValue<T>(string name)
{
if (!repo.OfType<MyDictionary<T>>().Any())
return default(T);//or throw
else
{
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
return dict[name];
}
}
}
And finally you may use this repository:
MyRepository repo = new MyRepository();
repo.Add("A", 1);
repo.Add("B", 1);
int i = repo.GetValue<int>("A") + repo.GetValue<int>("B");
In this example, there is MyDictionary<T> boxing to object is left.
From the other side, if your are working with some certain types you may not use thie repository class at all. But utilize separate dictionaties.
MyDictionary<int> intDict = new MyDictionary<int>();
intDict["A"] = 1;
intDict["B"] = 2;
int i = intDict["A"] + intDict["B"];
However it's the same as working with
Dictionary<string, int> intDict = new Dictionary<string, int>();
So the MyRepository class may be edited to use Dictionary<string, T> instead of MyDictionary<T>.
#Konstantin's answer made me remember that there is actually a very fast lookup method - array indexing. This crude PoC code shows a variant of the required structure.
public class TypeDictionary {
static int _maxId = 0;
int _id;
static class Store<T>{
internal static List<T> Values = new List<T>();
}
public TypeDictionary() {
_id = _maxId++;
}
public T GetValue<T>() {
return Store<T>.Values[_id];
}
public void SetValue<T>(T value) {
while(Store<T>.Values.Count < _id) {
Store<T>.Values.Add(default(T));
}
Store<T>.Values[_id] = value;
}
}
This code can be used as follows:
var dict1 = new TypeDictionary();
dict1.SetValue("my string");
string result = dict1.GetValue<string>();
The problem with this solution is it's memory usage caused by the repository being not sparse. This also makes first time value setting more expensive.
Try this:
public class MyDictionary
{
List<object> values;
public MyDictionary()
{
values = new List<object>();
}
public T GetValue<T>()
{
return values.OfType<T>().FirstOrDefault();
}
public bool Add<T>(T value)
{
if (values.OfType<T>().Any())
return false;
else
{
values.Add(value);
return true;
}
}
}
and use it:
var md = new MyDictionary();
md.Add("!!!");
string s = md.GetValue<string>();
This class may store up to one value of type T. But there could corner cases with derived classes and interfaces I guess. You may check, if it suits your need, and probably modify it as you need, if it's close to what you need in general.
What you are looking for is impossible in C#. The language does not support a container that could store multiple objects of different types yet provides a look up method that does not involve casting, boxing or unboxing. You could accomplish something like this with macros in C++, or via a language like javascript where the structure of types can be changed at run-time.
The usage case you are describing fits quite closely with the purpose for which ConditionalWeakTable<TKey,TValue> was added to .NET 4.0. For the purpose you describe, you would include such a table in a static generic class, and then for every class object that's supposed to contain a reference to an item of a particular type you would store into that type's table a reference to object that's supposed to contain the item along with either a reference to the item, or else a reference to a simple item-holder object (note that entries in ConditionalWeakTable will evaporate when an object ceases to exist, but are otherwise immutable, so if you want a mutable association you'll need to create an object to hold it).
Building on #phoog's example with #supercat's suggestion
public class TypeDict
{
public T Get<T>() where T : class
{
T value;
InnerDict<T>.Values.TryGetValue(this, out value);
return value;
}
public void Set<T>(T value) where T : class
{
var cwt = InnerDict<T>.Values;
// lock+remove+add https://github.com/dotnet/coreclr/issues/4545
lock (cwt)
{
cwt.Remove(this);
cwt.Add(this, value);
}
}
private static class InnerDict<T> where T : class
{
public static ConditionalWeakTable<TypeDict, T> Values { get; private set; }
static InnerDict()
{
Values = new ConditionalWeakTable<TypeDict, T>();
}
}
}

Strongly-typed Search functionality for class?

I am trying to figure out something with c# code, and I'm not 100% sure if it is possible, but I am trying to implement search functionality for several classes which is streamlined and overall easy to develop for. Right now I have the following code:
[DataContract(IsReference = true), Serializable]
public class ClassSearch
{
[DataMember]
public string Name { get; set; }
[DataMember]
public object Value { get; set; }
public override string ToString()
{
return String.Format("{0} = {1}", Name, Value);
}
... // additional logic
}
However, I would like to include strong typing for the object value so that it only can be set to the property that is passed in, I guess like similar (hypothetical, not sure if this would work)
[DataContract(IsReference = true), Serializable]
public class ClassSearch<TProperty>
{
[DataMember]
public TProperty Property {get; set; }
public override string ToString()
{
return String.Format("{0} = '{1}'", Property.Name, Property);
}
... // additional logic
}
public class MainClass
{
public void Execute()
{
SomeClass someClass = new Class{
Property = "Value";
};
ClassSearch search = new ClassSearch<SomeClass.Property>{
Property = someClass.Property
};
var retString = search.ToString(); // Returns "Property = 'Value'"
}
}
It seems you are trying to create a WCF service to be able to pass any type you like.
First of all, this is not WSDL-friendly. All WCF services needs to be able to be exposed in WSDL. WSDL is all about well-defined contracts hence the types need be all defined. So that generic approach would not work - mainly because of WSDL. Having said that, you still can use generics but then you have to use KnownType and actually define all the types possible - which for me defeats the object.
Yet, one thing you can do is to serialize the object yourself and pass around with its type name across the wire. On the other side, you can pick it up deserialize.
So something along the line of:
// NOTE: Not meant for production!
[DataContract]
public class GenericWcfPayload
{
[DataMember]
public byte[] Payload {get; set;}
[DataMember]
public string TypeName {get; set;}
}
If there are no easier answers I would try it with this one.
You could use expressions like so:
// Sample object with a property.
SomeClass someClass = new SomeClass{Property = "Value"};
// Create the member expression.
Expression<Func<object /*prop owner object*/, object/*prop value*/>> e =
owner => ((SomeClass)owner).Property;
// Get property name by analyzing expression.
string propName = ((MemberExpression)e.Body).Member.Name;
// Get property value by compiling and running expression.
object propValue = e.Compile().Invoke(someClass);
You hand over your property by the member expression owner => ((SomeClass)owner).Property. This expression contains both information you need: property name and property value. The last two lines show you how to get name and value.
Following a larger example:
class MainClass
{
public static void Execute()
{
SomeClass someClass = new SomeClass{
Property = "Value"
};
var search = new ClassSearch(s => ((SomeClass)s).Property);
Console.Out.WriteLine("{0} = '{1}'", search.Property.Name, search.Property.GetValue(someClass));
}
}
class Reflector
{
public static string GetPropertyName(Expression<Func<object, object>> e)
{
if (e.Body.NodeType != ExpressionType.MemberAccess)
{
throw new ArgumentException("Wrong expression!");
}
MemberExpression me = ((MemberExpression) e.Body);
return me.Member.Name;
}
}
class ClassSearch
{
public ClassSearch(Expression<Func<object, object>> e)
{
Property = new PropertyNameAndValue(e);
}
public PropertyNameAndValue Property { get; private set; }
public override string ToString()
{
return String.Format("{0} = '{1}'", Property.Name, Property);
}
}
class PropertyNameAndValue
{
private readonly Func<object, object> _func;
public PropertyNameAndValue(Expression<Func<object, object>> e)
{
_func = e.Compile();
Name = Reflector.GetPropertyName(e);
}
public object GetValue(object propOwner)
{
return _func.Invoke(propOwner);
}
public string Name { get; private set; }
}
class SomeClass
{
public string Property { get; set; }
}
The main part of that example is the method Reflector.GetPropertyName(...) that returns the name of a property within an expression. I.e. Reflector.GetPropertyName(s => ((SomeClass)s).Property) would return "Property".
The advantage is: This is type-safe because in new ClassSearch(s => s.Property) compiling would end with an error if SomeClass would not have a property 'Property'.
The disadvantage is: This is not type-safe because if you write e.g. new ClassSearch(s => s.Method()) and there would be a method 'Method' then there would be no compile error but a runtime error.

C# Property Reference

Given the following code;
public class CustomControl {
private object _dataItem;
public object DataItem {
get { return _dataItem; }
set { _dataItem = value; }
}
public void Update(ref string t) {
t = "test";
}
}
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
string prop = anyObject.anyProperty;
ctrl.Update(ref prop);
anyObject.anyProperty = prop;
}
}
How can I change it so that the DataItem property is itself a reference, allowing you to pre-emptively set it to point to a variable thus allowing you to call Update() without any parameters.
So the Consume class would then look similar to;
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
ctrl.Update();
// anyObject.anyProperty has been updated to "test"
}
}
So the assigment of anyObject.anyProperty is then handled internally within CustomControl
You need to store the act of setting something to a string, so store an Action<string>:
public class CustomControl {
public Action<string> SetData { get; set; }
public void Update() {
// TODO nullity check
SetData("test");
}
}
Then Consume would look like:
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
// store {the act of setting this property of this object to a string}
ctrl.SetData = s => anyObject.anyProperty = s;
ctrl.Update();
}
}
The Update call will set anyObject.anyProperty to test. Note that you are storing specifically the act of setting this property of the particular anyObject you refer to in the assignment to SetData.
To expand on the lambda: we want to create a value of type Action<string>, that is, a thing which takes a string and returns no result. Such a thing is going to be executable code. Prior to C# 3, to create a 'value' that was executable code, we would have had to do something like:
ctrl.SetData = delegate(string s) { someObject.SomeProperty = s; };
With this syntax it's more obvious that we're creating a method - it has a { } delimited body, it has statements in it, and it's clear there is a string parameter that is used by the body.
One thing achieved by lambda expressions in C# 3 is the ability to condense this down; loosely, the whole of
// not compilable code
delegate(parameters) { body; }
can be replaced with
// not compilable code
(parameters) => body;
and in the case where there's only one parameter
// not compilable code
parameter => body;
which is what we have here: the expression assigned to ctrl.SetData is a piece of behaviour that accepts a string (s) and sets anyObject.anyProperty to that string. The real power is in the way the C# compiler can work out the types to it know we're creating an Action<string>.
At first I didn't understand what you're trying to do. What you're looking for is the Adapter or Facade pattern. That is, you have an object with a particular interface, but you need to adapt it to a different interface or provide a simpler interface.
One way to implement these patterns is to use composition and delegate the new interface to methods on the existing interface.
public interface IUpdatable<U>
{
void Update( U newValue );
}
public abstract class CustomControl<T,U> : IUpdatable<U>
where T : Control
{
private T Control { get; set; }
protected CustomControl( T control )
{
this.Control = control;
}
public abstract void Update( U newValue );
}
public class TextBoxFacade : CustomControl<TextBox,string>, IUpdatable<string>
{
public TextBoxFacade( TextBox textbox ) : base(textbox) { }
public override void Update( string newValue )
{
this.Control.Value = newValue;
}
}

What is the best way to give a C# auto-property an initial value?

How do you give a C# auto-property an initial value?
I either use the constructor, or revert to the old syntax.
Using the Constructor:
class Person
{
public Person()
{
Name = "Initial Name";
}
public string Name { get; set; }
}
Using normal property syntax (with an initial value)
private string name = "Initial Name";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Is there a better way?
In C# 5 and earlier, to give auto implemented properties an initial value, you have to do it in a constructor.
Since C# 6.0, you can specify initial value in-line. The syntax is:
public int X { get; set; } = x; // C# 6 or higher
DefaultValueAttribute is intended to be used by the VS designer (or any other consumer) to specify a default value, not an initial value. (Even if in designed object, initial value is the default value).
At compile time DefaultValueAttribute will not impact the generated IL and it will not be read to initialize the property to that value (see DefaultValue attribute is not working with my Auto Property).
Example of attributes that impact the IL are ThreadStaticAttribute, CallerMemberNameAttribute, ...
Edited on 1/2/15
C# 6 :
With C# 6 you can initialize auto-properties directly (finally!), there are now other answers that describe that.
C# 5 and below:
Though the intended use of the attribute is not to actually set the values of the properties, you can use reflection to always set them anyway...
public class DefaultValuesTest
{
public DefaultValuesTest()
{
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
{
DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
if (myAttribute != null)
{
property.SetValue(this, myAttribute.Value);
}
}
}
public void DoTest()
{
var db = DefaultValueBool;
var ds = DefaultValueString;
var di = DefaultValueInt;
}
[System.ComponentModel.DefaultValue(true)]
public bool DefaultValueBool { get; set; }
[System.ComponentModel.DefaultValue("Good")]
public string DefaultValueString { get; set; }
[System.ComponentModel.DefaultValue(27)]
public int DefaultValueInt { get; set; }
}
When you inline an initial value for a variable it will be done implicitly in the constructor anyway.
I would argue that this syntax was best practice in C# up to 5:
class Person
{
public Person()
{
//do anything before variable assignment
//assign initial values
Name = "Default Name";
//do anything after variable assignment
}
public string Name { get; set; }
}
As this gives you clear control of the order values are assigned.
As of C#6 there is a new way:
public string Name { get; set; } = "Default Name";
Sometimes I use this, if I don't want it to be actually set and persisted in my db:
class Person
{
private string _name;
public string Name
{
get
{
return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
}
set { _name = value; }
}
}
Obviously if it's not a string then I might make the object nullable ( double?, int? ) and check if it's null, return a default, or return the value it's set to.
Then I can make a check in my repository to see if it's my default and not persist, or make a backdoor check in to see the true status of the backing value, before saving.
In C# 6.0 this is a breeze!
You can do it in the Class declaration itself, in the property declaration statements.
public class Coordinate
{
public int X { get; set; } = 34; // get or set auto-property with initializer
public int Y { get; } = 89; // read-only auto-property with initializer
public int Z { get; } // read-only auto-property with no initializer
// so it has to be initialized from constructor
public Coordinate() // .ctor()
{
Z = 42;
}
}
Starting with C# 6.0, We can assign default value to auto-implemented properties.
public string Name { get; set; } = "Some Name";
We can also create read-only auto implemented property like:
public string Name { get; } = "Some Name";
See: C# 6: First reactions , Initializers for automatically implemented properties - By Jon Skeet
In Version of C# (6.0) & greater, you can do :
For Readonly properties
public int ReadOnlyProp => 2;
For both Writable & Readable properties
public string PropTest { get; set; } = "test";
In current Version of C# (7.0), you can do : (The snippet rather displays how you can use expression bodied get/set accessors to make is more compact when using with backing fields)
private string label = "Default Value";
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value;
}
In C# 9.0 was added support of init keyword - very useful and extremly sophisticated way for declaration read-only auto-properties:
Declare:
class Person
{
public string Name { get; init; } = "Anonymous user";
}
~Enjoy~ Use:
// 1. Person with default name
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
// > Hello, Anonymous user!
// 2. Person with assigned value
var me = new Person { Name = "#codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// > Hello, #codez0mb1e!
// 3. Attempt to re-assignment Name
me.Name = "My fake";
// > Compilation error: Init-only property can only be assigned in an object initializer
In addition to the answer already accepted, for the scenario when you want to define a default property as a function of other properties you can use expression body notation on C#6.0 (and higher) for even more elegant and concise constructs like:
public class Person{
public string FullName => $"{First} {Last}"; // expression body notation
public string First { get; set; } = "First";
public string Last { get; set; } = "Last";
}
You can use the above in the following fashion
var p = new Person();
p.FullName; // First Last
p.First = "Jon";
p.Last = "Snow";
p.FullName; // Jon Snow
In order to be able to use the above "=>" notation, the property must be read only, and you do not use the get accessor keyword.
Details on MSDN
In C# 6 and above you can simply use the syntax:
public object Foo { get; set; } = bar;
Note that to have a readonly property simply omit the set, as so:
public object Foo { get; } = bar;
You can also assign readonly auto-properties from the constructor.
Prior to this I responded as below.
I'd avoid adding a default to the constructor; leave that for dynamic assignments and avoid having two points at which the variable is assigned (i.e. the type default and in the constructor). Typically I'd simply write a normal property in such cases.
One other option is to do what ASP.Net does and define defaults via an attribute:
http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
My solution is to use a custom attribute that provides default value property initialization by constant or using property type initializer.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InstanceAttribute : Attribute
{
public bool IsConstructorCall { get; private set; }
public object[] Values { get; private set; }
public InstanceAttribute() : this(true) { }
public InstanceAttribute(object value) : this(false, value) { }
public InstanceAttribute(bool isConstructorCall, params object[] values)
{
IsConstructorCall = isConstructorCall;
Values = values ?? new object[0];
}
}
To use this attribute it's necessary to inherit a class from special base class-initializer or use a static helper method:
public abstract class DefaultValueInitializer
{
protected DefaultValueInitializer()
{
InitializeDefaultValues(this);
}
public static void InitializeDefaultValues(object obj)
{
var props = from prop in obj.GetType().GetProperties()
let attrs = prop.GetCustomAttributes(typeof(InstanceAttribute), false)
where attrs.Any()
select new { Property = prop, Attr = ((InstanceAttribute)attrs.First()) };
foreach (var pair in props)
{
object value = !pair.Attr.IsConstructorCall && pair.Attr.Values.Length > 0
? pair.Attr.Values[0]
: Activator.CreateInstance(pair.Property.PropertyType, pair.Attr.Values);
pair.Property.SetValue(obj, value, null);
}
}
}
Usage example:
public class Simple : DefaultValueInitializer
{
[Instance("StringValue")]
public string StringValue { get; set; }
[Instance]
public List<string> Items { get; set; }
[Instance(true, 3,4)]
public Point Point { get; set; }
}
public static void Main(string[] args)
{
var obj = new Simple
{
Items = {"Item1"}
};
Console.WriteLine(obj.Items[0]);
Console.WriteLine(obj.Point);
Console.WriteLine(obj.StringValue);
}
Output:
Item1
(X=3,Y=4)
StringValue
little complete sample:
using System.ComponentModel;
private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
get { return bShowGroup; }
set { bShowGroup = value; }
}
You can simple put like this
public sealed class Employee
{
public int Id { get; set; } = 101;
}
In the constructor. The constructor's purpose is to initialized it's data members.
private string name;
public string Name
{
get
{
if(name == null)
{
name = "Default Name";
}
return name;
}
set
{
name = value;
}
}
Have you tried using the DefaultValueAttribute or ShouldSerialize and Reset methods in conjunction with the constructor? I feel like one of these two methods is necessary if you're making a class that might show up on the designer surface or in a property grid.
Use the constructor because "When the constructor is finished, Construction should be finished". properties are like states your classes hold, if you had to initialize a default state, you would do that in your constructor.
To clarify, yes, you need to set default values in the constructor for class derived objects. You will need to ensure the constructor exists with the proper access modifier for construction where used. If the object is not instantiated, e.g. it has no constructor (e.g. static methods) then the default value can be set by the field. The reasoning here is that the object itself will be created only once and you do not instantiate it.
#Darren Kopp - good answer, clean, and correct. And to reiterate, you CAN write constructors for Abstract methods. You just need to access them from the base class when writing the constructor:
Constructor at Base Class:
public BaseClassAbstract()
{
this.PropertyName = "Default Name";
}
Constructor at Derived / Concrete / Sub-Class:
public SubClass() : base() { }
The point here is that the instance variable drawn from the base class may bury your base field name. Setting the current instantiated object value using "this." will allow you to correctly form your object with respect to the current instance and required permission levels (access modifiers) where you are instantiating it.
public Class ClassName{
public int PropName{get;set;}
public ClassName{
PropName=0; //Default Value
}
}
This is old now, and my position has changed. I'm leaving the original answer for posterity only.
Personally, I don't see the point of making it a property at all if you're not going to do anything at all beyond the auto-property. Just leave it as a field. The encapsulation benefit for these item are just red herrings, because there's nothing behind them to encapsulate. If you ever need to change the underlying implementation you're still free to refactor them as properties without breaking any dependent code.
Hmm... maybe this will be the subject of it's own question later
class Person
{
/// Gets/sets a value indicating whether auto
/// save of review layer is enabled or not
[System.ComponentModel.DefaultValue(true)]
public bool AutoSaveReviewLayer { get; set; }
}
I know this is an old question, but it came up when I was looking for how to have a default value that gets inherited with the option to override, I came up with
//base class
public class Car
{
public virtual string FuelUnits
{
get { return "gasoline in gallons"; }
protected set { }
}
}
//derived
public class Tesla : Car
{
public override string FuelUnits => "ampere hour";
}
I think this would do it for ya givng SomeFlag a default of false.
private bool _SomeFlagSet = false;
public bool SomeFlag
{
get
{
if (!_SomeFlagSet)
SomeFlag = false;
return SomeFlag;
}
set
{
if (!_SomeFlagSet)
_SomeFlagSet = true;
SomeFlag = value;
}
}

Categories