Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Write-only properties are a rare beast, and don't exist in the System.ComponentModel / PropertyDescriptor space. <code>PropertyDescriptor</code>s are designed to be readable. I could probably hack <code>HyperDescriptor</code> to shim write-only properties, but it would be a hack - and it would presumably have to throw exceptions for <code>get</code>, which could impact calling code quite a bit.</p> <p>As an aside; I generally advise <em>against</em> write-only properties; the text-book example that people trot out is passwords (<code>public string Password {private get;set;}</code>) - I'd much rather have a <code>void SetPassword(string newPassword)</code> method...</p> <p>What is it that you actually want to do? There are a range of options here, all very achievable:</p> <ul> <li>use reflection alone (slow; maybe not an option)</li> <li>use <code>Delegate.CreateDelegate</code> (very easy)</li> <li>use <code>Expression.Compile</code> (a <em>little</em> harder, but not much)</li> <li>use <code>Reflection.Emit</code> (quite hard)</li> <li>shim write-only properties into <code>PropertyDescriptor</code> (quite hard)</li> </ul> <p>If you let me know what you actually want to do (rather than the way you are currently trying to do it), I might be able to help more.</p> <p>As an example using <code>Delegate.CreateDelegate</code> (note you would want to stash the delegate somewhere and re-use it lots of times):</p> <p><strong>edited to show how to do it if you don't know the specific types at runtime</strong></p> <pre><code>using System; using System.Reflection; class Foo { public string Bar { private get; set; } public override string ToString() { return Bar; // to prove working } } static class Program { static void Main() { ISetter setter = Setter.Create(typeof(Foo), "Bar"); Foo foo = new Foo(); setter.SetValue(foo, "abc"); string s = foo.ToString(); // prove working } } public interface ISetter { void SetValue(object target, object value); } public static class Setter { public static ISetter Create(Type type, string propertyName) { if (type == null) throw new ArgumentNullException("type"); if (propertyName == null) throw new ArgumentNullException("propertyName"); return Create(type.GetProperty(propertyName)); } public static ISetter Create(PropertyInfo property) { if(property == null) throw new ArgumentNullException("property"); if (!property.CanWrite) throw new InvalidOperationException("Property cannot be written"); Type type = typeof(TypedSetter&lt;,&gt;).MakeGenericType( property.ReflectedType, property.PropertyType); return (ISetter) Activator.CreateInstance( type, property.GetSetMethod()); } } public class TypedSetter&lt;TTarget, TValue&gt; : ISetter { private readonly Action&lt;TTarget, TValue&gt; setter; public TypedSetter(MethodInfo method) { setter = (Action&lt;TTarget, TValue&gt;)Delegate.CreateDelegate( typeof(Action&lt;TTarget, TValue&gt;), method); } void ISetter.SetValue(object target, object value) { setter((TTarget)target, (TValue)value); } public void SetValue(TTarget target, TValue value) { setter(target, value); } } </code></pre> <hr> <p>Or alternatively using the <code>Expression</code> API (.NET 3.5):</p> <pre><code>using System; using System.Linq.Expressions; using System.Reflection; class Foo { public string Bar { private get; set; } public override string ToString() { return Bar; // to prove working } } static class Program { static void Main() { Action&lt;object,object&gt; setter = Setter.Create(typeof(Foo), "Bar"); Foo foo = new Foo(); setter(foo, "abc"); string s = foo.ToString(); } } public static class Setter { public static Action&lt;object,object&gt; Create(Type type, string propertyName) { if (type == null) throw new ArgumentNullException("type"); if (propertyName == null) throw new ArgumentNullException("propertyName"); return Create(type.GetProperty(propertyName)); } public static Action&lt;object,object&gt; Create(PropertyInfo property) { if(property == null) throw new ArgumentNullException("property"); if (!property.CanWrite) throw new InvalidOperationException("Property cannot be written"); var objParam = Expression.Parameter(typeof(object), "obj"); var valueParam = Expression.Parameter(typeof(object), "value"); var body = Expression.Call( Expression.Convert(objParam, property.ReflectedType), property.GetSetMethod(), Expression.Convert(valueParam, property.PropertyType)); return Expression.Lambda&lt;Action&lt;object, object&gt;&gt;( body, objParam, valueParam).Compile(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload