Как обнаружить, если свойство существует на ExpandoObject?

Отредактировано для включения взвешенных сумм.

Это может быть очень приятный трюк, но наиболее простой (и обслуживаемый) способ - это, вероятно, простая for -цикличная реализация.

M1 <- matrix(1:16, nr=4)
M1
#      [,1] [,2] [,3] [,4]
# [1,]    1    5    9   13
# [2,]    2    6   10   14
# [3,]    3    7   11   15
# [4,]    4    8   12   16

Код:

get_neighbors <- function(M, radius = 1) {
  M2 <- M
  M2[] <- 0
  nr <- nrow(M)
  nc <- ncol(M)
  eg <- expand.grid((-radius):radius, (-radius):radius)
  eg$wt <- exp(-sqrt(abs(eg[,1]) + abs(eg[,2])))
  for (R in seq_len(nr)) {
    for (C in seq_len(nc)) {
      ind <- cbind(R + eg[,1], C + eg[,2], eg[,3])
      ind <- ind[ 0 < ind[,1] & ind[,1] <= nr &
                    0 < ind[,2] & ind[,2] <= nc,, drop = FALSE ]
      M2[R,C] <- sum(M[ind[,1:2, drop=FALSE]] * ind[,3])
    }
  }
  M2
}

get_neighbors(M1, 1)
#           [,1]     [,2]     [,3]     [,4]
# [1,]  5.033856 13.80347 24.16296 23.89239
# [2,]  8.596195 20.66391 34.43985 32.84175
# [3,] 11.186067 24.10789 37.88383 35.43163
# [4,]  9.748491 19.86486 30.22435 28.60703

То же самое, с радиусом 2:

get_neighbors(M1, 2)
#          [,1]     [,2]     [,3]     [,4]
# [1,] 12.44761 25.64963 31.73247 32.70974
# [2,] 18.57765 35.96237 43.33862 43.51911
# [3,] 20.09836 37.80643 45.18268 45.03982
# [4,] 17.51314 31.88500 37.96784 37.77527

И простой тест, если используется радиус 0, тогда M1 и M2 должны быть идентичны (они есть).

Примечание: это обычно выполняет очень хорошо в базе R, без всякого причудливого использования apply или его кузенов. Поскольку это действительно простая эвристика, ее можно легко реализовать с помощью Rcpp, чтобы она была значительно быстрее.

181
задан nawfal 19 July 2014 в 08:22
поделиться

5 ответов

В зависимости от Вашего варианта использования, если пустой указатель можно рассмотреть как совпадение с неопределенным, можно превратить ExpandoObject в DynamicJsonObject.

    dynamic x = new System.Web.Helpers.DynamicJsonObject(new ExpandoObject());
    x.a = 1;
    x.b = 2.50;
    Console.WriteLine("a is " + (x.a ?? "undefined"));
    Console.WriteLine("b is " + (x.b ?? "undefined"));
    Console.WriteLine("c is " + (x.c ?? "undefined"));

Вывод:

a is 1
b is 2.5
c is undefined
0
ответ дан 23 November 2019 в 06:11
поделиться

Эй, ребята, прекратите использовать Reflection для всего, что требует большого количества циклов процессора.

Вот решение:

public class DynamicDictionary : DynamicObject
{
    Dictionary<string, object> dictionary = new Dictionary<string, object>();

    public int Count
    {
        get
        {
            return dictionary.Count;
        }
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        string name = binder.Name;

        if (!dictionary.TryGetValue(binder.Name, out result))
            result = "undefined";

        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }
}
-3
ответ дан 23 November 2019 в 06:11
поделиться

Согласно MSDN объявление показывает, что он реализует IDictionary:

public sealed class ExpandoObject : IDynamicMetaObjectProvider, 
    IDictionary<string, Object>, ICollection<KeyValuePair<string, Object>>, 
    IEnumerable<KeyValuePair<string, Object>>, IEnumerable, INotifyPropertyChanged

Вы можете использовать это, чтобы увидеть, есть ли член определен:

var expandoObject = ...;
if(((IDictionary<String, object>)expandoObject).ContainsKey("SomeMember")) {
    // expandoObject.SomeMember exists.
}
177
ответ дан 23 November 2019 в 06:11
поделиться

Почему вы не хотите использовать Reflection для получения набора свойств типа? Вот так

 dynamic v = new Foo();
 Type t = v.GetType();
 System.Reflection.PropertyInfo[] pInfo =  t.GetProperties();
 if (Array.Find<System.Reflection.PropertyInfo>(pInfo, p => { return p.Name == "PropName"; }).    GetValue(v,  null) != null))
 {
     //PropName initialized
 } 
1
ответ дан 23 November 2019 в 06:11
поделиться

Недавно я ответил на очень похожий вопрос: Как мне размышлять над членами динамический объект?

Вкратце, ExpandoObject - не единственный динамический объект, который вы можете получить. Отражение будет работать для статических типов (типов, которые не реализуют IDynamicMetaObjectProvider). Для типов, реализующих этот интерфейс, отражение в основном бесполезно. Для ExpandoObject вы можете просто проверить, определено ли свойство как ключ в базовом словаре. Для других реализаций это может быть сложно, и иногда единственный способ - работать с исключениями. Для получения подробной информации перейдите по ссылке выше.

11
ответ дан 23 November 2019 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: