【问题标题】:Shorten syntax for nearly identical properties缩短几乎相同属性的语法
【发布时间】:2019-04-15 14:22:44
【问题描述】:

我不得不重新编写一些代码,并偶然发现了一些定义了大量非常相似的属性的类。

它们看起来像这样:

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

它们之间的唯一区别是_ReturnType、字典中使用的_stringProperties,显然还有_PropertyName

我想知道是否有办法缩短语法?

【问题讨论】:

标签: c# properties


【解决方案1】:

如果你看到重复的代码,你就提取了一个方法。它看起来像这样:

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 cmets,这听起来像是代码生成的理想场景,因为没有它,您仍然会有几行(复制粘贴,容易出错)代码。

这些属性应该命名的地方可能有一个来源,您可以使用 T4 模板之类的东西从中生成此代码文件。

【讨论】:

    【解决方案2】:

    好吧,你可以这样做:

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

    【讨论】:

      【解决方案3】:

      如果Properties 实现IReadOnlyDictionary&lt;string, object&gt;(例如Dictionary&lt;string, object&gt;),您可以做的一件事是添加一个扩展方法:

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

      Link to Fiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 2019-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-04
        相关资源
        最近更新 更多