Home > c# > Using ref on Properties

Using ref on Properties

September 10Hits:0
Advertisement

I'm trying to do do the following:

GetString(     inputString,     ref Client.WorkPhone)  private void GetString(string inValue, ref string outValue) {     if (!string.IsNullOrEmpty(inValue))     {         outValue = inValue;     } } 

This is giving me a compile error. I think its pretty clear what I'm trying to achieve. Basically I want GetString to copy the contents of an input string to the WorkPhone property of Client.

Is it possible to pass a property by reference?

Answers

Properties cannot be passed by reference. Here are a few ways you can work around this limitation.

1. Return Value

string GetString(string input, string output)
{
    if (!string.IsNullOrEmpty(input))
    {
        return input;
    }
    return output;
}

void Main()
{
    var person = new Person();
    person.Name = GetString("test", person.Name);
    Debug.Assert(person.Name == "test");
}

2. Delegate

void GetString(string input, Action<string> setOutput)
{
    if (!string.IsNullOrEmpty(input))
    {
        setOutput(input);
    }
}

void Main()
{
    var person = new Person();
    GetString("test", value => person.Name = value);
    Debug.Assert(person.Name == "test");
}

3. LINQ Expression

void GetString<T>(string input, T target, Expression<Func<T, string>> outExpr)
{
    if (!string.IsNullOrEmpty(input))
    {
        var expr = (MemberExpression) outExpr.Body;
        var prop = (PropertyInfo) expr.Member;
        prop.SetValue(target, input, null);
    }
}

void Main()
{
    var person = new Person();
    GetString("test", person, x => x.Name);
    Debug.Assert(person.Name == "test");
}

4. Reflection

void GetString(string input, object target, string propertyName)
{
    if (!string.IsNullOrEmpty(input))
    {
        prop = target.GetType().GetProperty(propertyName);
        prop.SetValue(target, input);
    }
}

void Main()
{
    var person = new Person();
    GetString("test", person, "Name");
    Debug.Assert(person.Name == "test");
}

without duplicating the property

void Main()
{
    var client = new Client();
    NullSafeSet("test", s => client.Name = s);
    Debug.Assert(person.Name == "test");

    NullSafeSet("", s => client.Name = s);
    Debug.Assert(person.Name == "test");

    NullSafeSet(null, s => client.Name = s);
    Debug.Assert(person.Name == "test");
}

void NullSafeSet(string value, Action<string> setter)
{
    if (!string.IsNullOrEmpty(value))
    {
        setter(value);
    }
}

Another trick not yet mentioned is to have the class which implements a property (e.g. Foo of type Bar) also define a delegate delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2); and implement a method ActOnFoo<TX1>(ref Bar it, ActByRef<Bar,TX1> proc, ref TX1 extraParam1) (and possibly versions for two and three "extra parameters" as well) which will pass its internal representation of Foo to the supplied procedure as a ref parameter. This has a couple of big advantages over other methods of working with the property:

  1. The property is updated "in place"; if the property is of a type that's compatible with `Interlocked` methods, or if it is a struct with exposed fields of such types, the `Interlocked` methods may be used to perform atomic updates to the property.
  2. If the property is an exposed-field structure, the fields of the structure may be modified without having to make any redundant copies of it.
  3. If the `ActByRef` method passes one or more `ref` parameters through from its caller to the supplied delegate, it may be possible to use a singleton or static delegate, thus avoiding the need to create closures or delegates at run-time.
  4. The property knows when it is being "worked with". While it is always necessary to use caution executing external code while holding a lock, if one can trust callers not to do too do anything in their callback that might require another lock, it may be practical to have the method guard the property access with a lock, such that updates which aren't compatible with `CompareExchange` could still be performed quasi-atomically.

Passing things be ref is an excellent pattern; too bad it's not used more.

This is covered in section 7.4.1 of the C# language spec. Only a variable-reference can be passed as a ref or out parameter in an argument list. A property does not qualify as a variable reference and hence cannot be used.

This is not possible. You could say

Client.WorkPhone = GetString(inputString, Client.WorkPhone);

where WorkPhone is a writeable string property and the definition of GetString is changed to

private string GetString(string in, string current) {
    if (!string.IsNullOrEmpty(in)) {
        return in;
    }
    return current;
}

This will have the same semantics that you seem to be trying for.

This isn't possible because a property is really a pair of methods in disguise. Each property makes available getters and setters that are accessible via field-like syntax. When you attempt to call GetString as you've proposed, what you're passing in is a value and not a variable. The value that you are passing in is that returned from the getter get_WorkPhone.

What you could try to do is create an object to hold the property value. That way you could pass the object and still have access to the property inside.

Just a little expansion to Nathan's Linq Expression solution. Use multi generic param so that the property doesn't limited to string.

void GetString<TClass, TProperty>(string input, TClass outObj, Expression<Func<TClass, TProperty>> outExpr)
{
    if (!string.IsNullOrEmpty(input))
    {
        var expr = (MemberExpression) outExpr.Body;
        var prop = (PropertyInfo) expr.Member;
        if (!prop.Equals(input))
        {
            prop.SetValue(outObj, input, null);
        }
    }
}

Related Articles

  • Using ref on Properties September 10

    I'm trying to do do the following: GetString( inputString, ref Client.WorkPhone) private void GetString(string inValue, ref string outValue) { if (!string.IsNullOrEmpty(inValue)) { outValue = inValue; } } This is giving me a compile error. I think it

  • Filtering by a ref's properties in App Engine using ObjectifyJanuary 14

    Hypothetical code: @Entity public class MyEvent { @Id Long id; @Index String name; Ref<Location> myLocation; } @Entity public class Location { @Id Long id; @Index String city; @Index String country; } Is there a way for me to do a filter to find all

  • creating multiple properties in property bagMay 24

    I want to know how to create multiple properties in property bag in sharepoint 2013 management shell. Now i have pretty long list like below $farm = Get-SPFarm $propName = "NameOfSite" $propValue = "http://mysite" $farm.Properties.Add(

  • Is throwing an exception from a property bad form?November 3

    I've always been of the mindset that properties (ie, their set/get operations) should be fast/immediate and failure-free. You should never have to try/catch around getting or setting a property. But I'm looking at some ways to apply role-based securi

  • Multiple Similar Tables vs One Master TableJuly 23

    I'm a web app developer and less experienced in database design, so would appreciate anyone's input. When I first built this web app, the app managed one type of object (table) with a handful of properties (columns). As the app grew, there were addit

  • getting System.NullPointerException: Attempt to de-reference a null objectSeptember 12

    in Execute Anonymous, executing the following code to test the class: List<Contact> contacts = [Select c.Territory__c, c.Sub_county_Code__c, c.Student_Type__c, c.Domestic_Or_International__c, c.Recruiter_Code__c, c.Name, c.MailingState, c.Home_Schoo

  • When using MVVM, should you create new viewmodels, or swap out the models?October 1

    Say I have a viewmodel like this: public class EmployeeViewModel { private EmployeeModel _model; public Color BackgroundColor { get; set; } public Name { get { return _model.Name; } set { _model.Name = value; NotifyPropertyChanged(Name); } } } So thi

  • Building a Recipe Search Site with Angular and ElasticsearchApril 15

    Have you ever wanted to build a search feature into an application? In the old days, you might have found yourself wrangling with Solr, or building your own search service on top of Lucene - if you were lucky. But, since 2010, there's been an easier

  • Can TemporalData be used as a container for TimeSeries and TimeSeries MetadataAugust 12

    When I create two TimeSeries with some MetaInformation I can combine them into one TemporalData object. But I lose the MetaInformation for the TimeSeries objects. ts1 = TimeSeries[{{1, 2}, {2, 5}, {3, 7}, {4, 3}}, MetaInformation -> {"signaalnaam&

  • Class design for JSON serializationMarch 20

    I've been stuck for some time on a circular reference issue with JSON serialization. I have a card game that I'm pickling to a redis store. As I retrieve the Game state from redis I'm trying to serialize it in JSON so that I can pass it to React.js a

  • Getting a mysterious missing field error creating a compute.v1.instanceTemplate with Deployment ManagerOctober 3

    I'm attempting to create a compute.v1.instanceTemplate with the Deployment Manager (v2), but I'm getting the following error: Unexpected response from resource of type compute.v1.instanceTemplate: 400 {statusMessage=Bad Request, errors=[{message=Inva

  • Can Spring Data REST's QueryDSL integration be used to perform more complex queries?February 2

    I'm currently building a REST API in which I want clients to easily filter on most properties of a specific entity. Using QueryDSL in combination with Spring Data REST (an example by Oliver Gierke) allows me to easily get to 90% of what I want by all

  • get the value of a given key from json array of objects in meteorFebruary 10

    This meteor code has menuItems to populate a li in the template. When an item is clicked, I need to get the value of the "login" key from the object that was clicked. I could not use menuItems.find(); because it is not a mongo collection. I coul

  • Can't open folder properties dialog in c# using wpf December 20

    how to open an file's Properties dialog by a button private void button_Click(object sender, EventArgs e) { string path = @"C:\Users\test\Documents\tes.text"; // how to open this propertie } Thank you. For example if want the System properties P

  • Tool to modify properties/metadata of a PDF? i.e. Change "Title", "Author"? Sony Reader showing some books as "untitled."March 13

    I own a Sony Reader PRS-600 ebook reader. I bought a ton of Manning Publications ebooks (DRM-free) recently. Many of the books are PDFs since not all the ones I wanted are available in epub format. The problem: Some of the PDF books I purchased have

  • svnsync loses revision properties although hook installedMay 17

    I have a pretty weird problem. We have setup an SVN-Mirror via cronjob (because it needs to go from inside to outside of a firewall, so no post-commit-hook possible) and svnsync. We installed a pre-revprop-hook just as told. Everything seems to work

  • Why does System Properties display two different frequencies?

    Why does System Properties display two different frequencies?June 11

    My System Properties window has the below text (also see screenshot). What does the "1.20 GHz " refer to? Hewlett-Packard HP Compaq dc7700p Convertible Intel(R) Core(TM)2 Duo CPU E4400 @ 2.00GHz 1.20 GHz 3.50 GB of RAM Physical Address Extension

  • Windows Explorer replacement which allows creating custom file propertiesSeptember 2

    I'm looking for a Windows Explorer replacement that has the following feature in some way or another: The ability to create custom properties for files. by saying properties, I refer to fields like "Size" or "Date Modified" which all f

  • Installed memory 4GB but only 1.93 GB is usable shows in system properties dialog?January 21

    In my Intel Core i5 2.80 GHz CPU , DH55HC series Intel mother board machine installed with windows 7 64 bit machine, when I right click my computer and see system properties I see that "Installed Memory(RAM): 4 GB(1.93 usable)".I have 2 x 2 GB D

  • Scheduled Tasks Properties in PowerShell?May 31

    I am not sure how to do this in PowerShell, but I dont think it is supported. For example: $tasks = schtasks /query Will store all the tasks into the variable $tasks Example output: Folder: \Microsoft\Windows\WindowsBackup TaskName Next Run Time Stat

Copyright (C) 2017 ceus-now.com, All Rights Reserved. webmaster#ceus-now.com 14 q. 0.331 s.