Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# properties as array notation

Using JavaScript it's possible to access an object using the dot notation or array notation.

var myArray = {e1:"elem1",e2:"elem2",e3:"elem3",e4:"elem4"};
var val1 = myArray["e1"];
var val2 = myArray.e1;

Is it possible to accomplish this using C#?

This is what I have attempted:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection frmVals)
{
  string value;
  Owner owner = new Owner();

  foreach (var key in frmVals.AllKeys)
  {
    value = frmVals[key];
    owner[key] = value;  
  }
}
like image 719
deDogs Avatar asked Jan 28 '11 17:01

deDogs


4 Answers

While there is no way to do this exactly with C#. You could change your code in several ways that may accomplish your goal. First, you could use a Dictionary like this:

var something = new Dictionary<string, object>() {
    { "property", "value"},
    { "property1", 1}
};
foreach (var keyVal in something) {
    var property = keyVal.Key;
    var propertyValue = keyVal.Value;
}

Another option would be to do it dynamically:

dynamic somethingDyn = new System.Dynamic.ExpandoObject();
somethingDyn.property = "value";
somethingDyn.property1 = 1;

var somethingDynDict = (IDictionary<string, object>)somethingDyn;
var propValue = somethingDyn["property"];

foreach (var keyVal in somethingDynDict) {
    var property = keyVal.Key;
    var propertyValue = keyVal.Value;
}

If you need to iterate through properties on a strongly typed object you could use reflection:

var owner = new Metis.Domain.User();
var properties = owner.GetType().GetProperties();
foreach (var prop in properties) {
    object value = prop.GetValue(owner, null);
}
like image 66
Nathan Totten Avatar answered Oct 22 '22 20:10

Nathan Totten


I wouldn't recommend this, but you could put an indexer in your class, accepting a string, then use reflection to read that property. Something like:

public object this[string key]
{
  get
  {
    var prop = typeof(ThisClassName).GetProperty(key);
    if (prop != null)
    {
      return prop.GetValue(this, null);
    }
    return null;
  }
  set
  {
    var prop = typeof(ThisClassName).GetProperty(key);
    if (prop != null)
    {
      prop.SetValue(this, value, null);
    }
  }
}
like image 42
Joe Enos Avatar answered Oct 22 '22 18:10

Joe Enos


Javascript array notation is not something you can use in C#.

You need to use dot notation to access members of an object.

You will need to access each value directly and assign it:

owner.key = frmVals[key];
owner.key2 = frmVals[key2];

There are workarounds - using dictionaries, dynamic objects or even reflection, but the scenario is not a directly supported by C#.

like image 32
Oded Avatar answered Oct 22 '22 19:10

Oded


There is no syntactic equivalent possible in C# but there are some ways to approximate the same feature.

You could mimic the indexer type access using a Dictionary but then you'd lose the property-style access. For property-style access, you could do something similar in C# by using an anonymous type, as in:

var myType = new { e1="elem1",e2="elem2",e3="elem3",e4="elem4"};
var val1 = myType.e1;

However, that doesn't create an array or allow array type access and it doesn't allow for modifications to the type after creation.

To get a closer approximation to the JavaScript feature, you may be able to use ExpandoObject to mimic this a little more closely, or you could implement something yourself.

For that, you'd need a class that has a constructor to auto-generate properties from the passed in array and exposes an indexer, which in turn uses reflection to find the named property.

Initialization of this type would be something like:

var myType = new MyType(new[]{
    {"e1", "elem1"},
    {"e2", "elem2"},
    {"e3", "elem3"},
    {"e4", "elem4"}});

This assumes there is a sub-type for each element definition (possibly using Tuple or KeyValuePair. The constructor would then be taking an IEnumerable<T> of that type.

like image 29
Jeff Yates Avatar answered Oct 22 '22 19:10

Jeff Yates