C#属性为数组表示法

时间:2011-01-28 17:31:03

标签: c# arrays properties

使用JavaScript可以使用点表示法或数组表示法访问对象。

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

是否可以使用C#完成此操作?

这就是我的尝试:

[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;  
  }
}

5 个答案:

答案 0 :(得分:6)

虽然没有办法完全用C#做到这一点。您可以通过多种方式更改代码,从而实现目标。首先,你可以使用这样的字典:

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

另一种选择是动态地做到这一点:

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;
}

如果需要遍历强类型对象的属性,可以使用反射:

var owner = new Metis.Domain.User();
var properties = owner.GetType().GetProperties();
foreach (var prop in properties) {
    object value = prop.GetValue(owner, null);
}

答案 1 :(得分:3)

我不推荐这个,但你可以在你的类中放一个索引器,接受一个字符串,然后使用反射来读取该属性。类似的东西:

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);
    }
  }
}

答案 2 :(得分:1)

Javascript数组表示法不是您可以在C#中使用的。

您需要使用点表示法来访问对象的成员。

您需要直接访问每个值并分配它:

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

有一些解决方法 - 使用字典,动态对象甚至反射,但C#不直接支持该场景。

答案 3 :(得分:1)

C#中没有可能的语法等价物,但有一些方法可以逼近相同的特征。

您可以使用Dictionary模仿索引器类型访问,但之后您将失去属性样式访问权限。对于属性样式访问,您可以使用匿名类型在C#中执行类似操作,如:

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

但是,这不会创建数组或允许数组类型访问,并且在创建后不允许对类型进行修改。

为了更接近JavaScript功能,您可以使用ExpandoObject来更接近地模仿这一点,或者您可以自己实现一些功能。

为此,您需要一个具有构造函数的类,以从传入的数组中自动生成属性并公开索引器,索引器又使用反射来查找命名属性。

此类型的初始化类似于:

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

这假设每个元素定义都有一个子类型(可能使用TupleKeyValuePair。然后构造函数将采用该类型的IEnumerable<T>

答案 4 :(得分:0)

是的,这是可能的。

有两种可能性:

1)键和值列表是动态的。

  • 阵列符号由例如提供。 System.Collections.Generic.Dictionary<string, blah>
  • 可以通过DLR magic和dynamic关键字提供成员访问权限表示法。

2)键和值列表是静态的。

  • 成员访问符号已由C#编译器提供。
  • 使用Reflection可以使用数组表示法(希望使用缓存来提高性能)。

在静态情况下,成员访问符号要快得多。在动态情况下,数组表示法会更快一些。