Свойства C # как обозначение массива - PullRequest
5 голосов
/ 28 января 2011

Используя 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 ]

6 голосов
/ 28 января 2011

Пока нет способа сделать это точно с 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);
}
3 голосов
/ 28 января 2011

Я бы не рекомендовал это, но вы могли бы добавить индексатор в ваш класс, принимая строку, а затем использовать отражение, чтобы прочитать это свойство. Что-то вроде:

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);
    }
  }
}
1 голос
/ 28 января 2011

Синтаксический эквивалент невозможен в 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"}});

Предполагается, что для каждого определения элемента существует подтип (возможно, с использованием Tuple или KeyValuePair. В этом случае конструктор будет принимать IEnumerable<T> этого типа.

1 голос
/ 28 января 2011

Нотация массива Javascript - это не то, что вы можете использовать в C #.

Вам необходимо использовать точечную нотацию для доступа к членам объекта.

Вам необходимо получить доступ к каждому значению напрямую и назначитьit:

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

Есть обходные пути - использование словарей, динамических объектов или даже отражения, но сценарий не поддерживается напрямую в C #.

0 голосов
/ 28 января 2011

Да, это возможно.

Существует две возможности:

1) Список ключей и значений является динамическим.

  • Предусмотрена запись массиванапример, System.Collections.Generic.Dictionary<string, blah>
  • Нотация доступа к члену может быть предоставлена ​​с помощью магии DLR и ключевого слова dynamic.

2) Список ключей и значений является статическим.

  • Обозначение доступа к члену уже предоставлено компилятором C #.
  • Обозначение массива можно использовать с помощью Reflection (возможно, с кэшем для повышения производительности).

В статическом случае нотация доступа к члену НАМНОГО быстрее.В динамическом случае нотация массива будет немного быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...