【问题标题】:How to make a field set-able only inside extension method如何使字段只能在扩展方法内部设置
【发布时间】:2019-03-09 20:14:12
【问题描述】:

您好,我希望能够仅在 extension 方法中设置对象字段的 a。我希望这个字段要么是完全私有的,要么只是来自外部的get-able:

public class Myclass
{
   private int Value{get;set;}
}
public static class Ext
{
   public Myclass SetValue(this Myclass obj,int val)
   {
       this.obj.Value=val;
       return obj;
   }
}

正如您在上面的示例中看到的,我必须声明 Value public 才能在扩展内访问它,如果我只能从外部创建变量 get-able,我会同意的。

我需要这个功能,因为我想开发类似 fluent api 的东西,你只能使用扩展设置一些变量。

例如:

      a=new Myclass();
      a.SetValue1(1).SetValue2(2);//--some code //--a.SetValue3(3);

【问题讨论】:

    标签: .net-core extension-methods fluent-interface


    【解决方案1】:

    听起来你使用了错误的工具来完成这项工作,扩展方法没有访问非公共成员。

    您想要的行为仅限于实例方法或属性。我的建议是在类中添加一个实例方法。

    如果这不能说服您,那么您可以改用反射来更新私有实例变量:

    public static class Ext
    {
        public Myclass SetValue(this Myclass obj,int val)
        {
            var myType = typeof(Myclass);
    
            var myField = myType.GetField("Value", BindingFlags.NonPublic | BindingFlags.Instance);
    
            myField.SetValue(obj, val);
    
            return obj;
       }
    }
    

    请注意,这有以下问题:

    1. 如果您决定重命名字段Value,则没有编译时检查可以节省您的时间。 (尽管单元测试可以保护你)
    2. 反射通常比常规实例方法慢得多。 (尽管如果不经常调用此方法,性能可能无关紧要)

    【讨论】:

      【解决方案2】:

      你希望它用扩展方法来做,但在这种情况下你不能。

      你最好的选择是

      public class Myclass
      {
         public int Value{get; private set;}
      
         public Myclass SetValue(int val)
         {
             this.Value=val;
      
             return obj;
         }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-02-02
        • 2020-06-26
        • 1970-01-01
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-05
        • 1970-01-01
        相关资源
        最近更新 更多