C# >变量的范围仅限于属性。 我希望在下一个版本的C中看到类似的语言结构:)

C# >变量的范围仅限于属性。 我希望在下一个版本的C中看到类似的语言结构:),c#,design-guidelines,C#,Design Guidelines,但是,恐怕这个功能永远不会实现: 这可能过于简单,但为什么不将所有的延迟抽象为一个基类呢 public class LazyFoo{ private string bar; public string Bar{ get{ // lazy load and return } set { // set } } } publ

但是,恐怕这个功能永远不会实现:

这可能过于简单,但为什么不将所有的延迟抽象为一个基类呢

 public class LazyFoo{
      private string bar;
      public string Bar{
         get{
             // lazy load and return
         }
         set {
             // set
         }
      }
    }

    public class Foo : LazyFoo{
      // only access the public properties here
    }

我可以认为这是不必要的抽象,但这是我所能看到的消除对支持字段的所有访问的最简单方法

这似乎是试图设计出一开始可能不会发生的错误,基本上是担心错误的事情

我会选择选项1+注释:

///<summary>use Bar property instead</summary> 
string bar;

///<summary>Lazy gets the value of Bar and stores it in bar</summary>
string Bar {
    get {
        // logic to lazy load bar  
        return bar; 
    }
}
///改用Bar属性
弦杆;
///Lazy获取Bar的值并将其存储在Bar中
弦杆{
得到{
//延迟加载条的逻辑
返回杆;
}
}
如果有一个开发人员一直使用backing变量,那么我会担心他们的技术能力

无论如何,设计要使您的代码更易于维护,但要尽量保持简单-您在这里为自己制定的任何规则都会比它的价值更麻烦


如果您仍然非常担心,请创建一个FxCop(或任何您正在使用的)规则来检查这类事情。

您能解释一下如何使此属性延迟加载吗?不,您不能以这种方式进行延迟实例化。但是如果你真的需要惰性,你可能会想花时间在一些东西上,比如一个用于惰性实例化的Lazy`1通用容器……这对我来说太复杂了——代码不错,但你增加了复杂性。我认为强制用户不使用备份字段的任何好处都会被可读性的降低所抵消。这确实应该得到+1,因为这是第四种方法,而且非常安全。即使一些盲人编码器使用这个.teValue.Value,他们仍然是安全的。。。当然,这一切只是一堆大象,因为现在你的懒惰加载程序有了最初的问题,懒惰真的很性感。。。我非常喜欢它。关于这个懒惰的实现,有一点需要考虑的是,它缺少一个锁,这是一个简单的修复方法。默认的实现不应该被锁定,只需支付您需要的费用,并避免复杂的锁定协议。但是,如果需要的话,提供ThreadSafeLazy是可以的。在某些情况下,多个创建调用实际上是好的,只要它在初始调用后稳定ones@Shaggy,这是我使用的实现,它执行一些基本的锁定和更改notification@sambo99您的实现会锁定每个访问。我建议你看看Joe Duffy的(这个家伙几乎就是.Net concurrecy的大师,+1我从来没有想过这一点,但我永远不会让这种丑陋进入我的代码库:)对不起-1,但这是一种邪恶的方式,任何人都不应该这样做。不过横向思维不错。@Rowland,+1,不过我还要加上“……并适当地培训您的无经验开发人员,使他们知道自己在做什么,并且不会破坏东西。”为什么要为支持领域使用您自己的名字呢?为什么不使用一个始终相同的新语言关键字(如设置期间的值)。为什么您认为任何使用str的人都会收到警告?这种代码最终会比您希望的更频繁地发送给客户
// option 4
class Foo
{
    public int PublicProperty { get; set; }
    public int PrivateSetter { get; private set; }
}
// I changed this with respect to ShuggyCoUk's answer (Kudos!)
class LazyEval<T>
{
  T value;
  Func<T> eval;
  public LazyEval(Func<T> eval) { this.eval = eval; }
  public T Eval()
  {
      if (eval == null)
          return value;
      value = eval();
      eval = null;
      return value;
  }
  public static implicit operator T(LazyEval<T> lazy) // maybe explicit
  {
    return lazy.Eval();
  }
  public static implicit operator LazyEval<T>(Func<T> eval) 
  {
    return new LazyEval(eval);
  } 
}
// option 5
class Foo
{
    public LazyEval<MyClass> LazyProperty { get; private set; }
    public Foo()
    {
        LazyProperty = () => new MyClass();
    }
}
// option 5
class Foo
{
    public int PublicProperty { get; private set; }
    public LazyEval<int> LazyProperty { get; private set; }
    public Foo()
    {
        LazyProperty = () => this.PublicProperty;
    }
    public void DoStuff()
    {
        var lazy = LazyProperty; // type is inferred as LazyEval`1, no eval
        PublicProperty = 7;
        int i = lazy; // same as lazy.Eval()
        Console.WriteLine(i); // WriteLine(7)
    }
}
string str = "SOMETHING_WRONG_HERE";
public int PropertyName { get; set; }
public class Foo {
  private class LazyLoader {
    private someType theValue;
    public someType Value {
      get {
        // Do lazy load
        return theValue;
      }
    }
  }

  private LazyLoader theValue;
  public someType {
    get { return theValue.Value; }
  }
}
    void Test1()
    {
        _prop = ""; // warning given
    }
    public string Prop
    {
#pragma warning disable 0618
        get { return _prop; }
        set { _prop = value; }
#pragma warning restore 0618
    }
    [Obsolete("This is the backing field for lazy data; do not use!!")]
    private string _prop;
    void Test2()
    {
        _prop = ""; // warning given
    }
/************************************************************
* Note: When updating this class, please take care of using *
*       only the accessors to access member data because of *
*       ... (state the reasons / your name, so they can ask *
*       questions)                                          *
*************************************************************/
public class MyClass
{
    public int MyProperty
    {
        int _backingField;

        get
        {
            return _backingField;
        }
        set
        {
            if( _backingField != value )
            {
                _backingField = value;
                // Additional logic
                ...
            }
        }
    }
}
 public class LazyFoo{
      private string bar;
      public string Bar{
         get{
             // lazy load and return
         }
         set {
             // set
         }
      }
    }

    public class Foo : LazyFoo{
      // only access the public properties here
    }
///<summary>use Bar property instead</summary> 
string bar;

///<summary>Lazy gets the value of Bar and stores it in bar</summary>
string Bar {
    get {
        // logic to lazy load bar  
        return bar; 
    }
}