Сократить синтаксис для почти идентичных свойств - PullRequest
0 голосов
/ 15 апреля 2019

Мне нужно переделать некоторый код и наткнуться на несколько классов, которые определяют огромное количество очень похожих свойств.

Они выглядят примерно так:

public _ReturnType _PropertyName
{
    get
    {
        IMarkerInterface value = null;
        if (Properties != null) Properties.TryGetValue(_string, out value);
        return value as _ReturnType;
    }
    set { Properties[_string] = value; }
}

Единственная разница междуэто _ReturnType, _string, который используется в словаре Properties и, очевидно, _PropertyName.

Мне было интересно, есть ли способ сократить синтаксис?

Ответы [ 3 ]

0 голосов
/ 15 апреля 2019

Если Properties реализует IReadOnlyDictionary<string, object> (например, Dictionary<string, object>), вы можете добавить метод расширения:

public static TValue TryGetValue<TValue>(
    this IReadOnlyDictionary<string, object> properties,
    string key)
    where TValue : class
{
    if ((properties != null) &&
         properties.TryGetValue(key, out object value))
    {
        return value as TValue;
    }

    return null;
}

, а затем

public IMarkerInterface MarkerInterface
{
  get => Properties.TryGetValue<IMarkerInterface>("MarkerInterface");
  set { Properties["MarkerInterface"] = value; }
}

Ссылка на скрипку

0 голосов
/ 15 апреля 2019

Ну, вы могли бы сделать это:

private IMarkerInterface getIMF(string str) 
{
    IMarkerInterface value = null;
    Properties?.TryGetValue(_string, out value);
    return value;
}

public _ReturnType _PropertyName
    {
      get { return getIMF(_string) as _ReturnType; }
      set { Properties[_string] = value; }
    }
0 голосов
/ 15 апреля 2019

Если вы видите повторяющийся код, вы извлекаете метод.Это будет выглядеть примерно так:

private T GetValueOrDefault<T>(string key)
{
    IMarkerInterface value = null;
    if (Properties != null) Properties.TryGetValue(key, out value);
    return value as T;
}

Затем измените ваш геттер:

get
{
    return GetValueOrDefault<_ReturnType>("key");
}

Но если этот код распределен по нескольким классам, вам придется определить базовый класссодержащий свойство Properties и вышеуказанный метод GetValueOrDefault(), хотя protected вместо private.

В качестве альтернативы вы можете определить его как метод расширения для любого типа Properties:

public static T GetValueOrDefault<T>(this IDictionary<string, IMarkerInterface> properties, string key)
{
    IMarkerInterface value = null;
    if (properties != null) properties.TryGetValue(key, out value);
    return value as T;
}

И назовите это так:

get
{
    return Properties.GetValueOrDefault<_ReturnType>("key");
}

Но, как комментирует @Daniel, это пахнет идеальным сценарием для генерации кода, потому что без этого у вас все равно останетсяпара строк (вставленных при копировании, подверженных ошибкам) ​​кода.

Возможно, где-то есть источник для именования этих свойств, и вы можете использовать что-то вроде шаблонов T4 для генерации этого файла кода изэто.

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