C# Equivalent for C++ Macros and using Auto<> Properties

ぐ巨炮叔叔 提交于 2019-12-05 17:51:28

问题


I have some auto-instantiation code which I would like to apply to about 15 properties in a fairly big class. The code is similar to the following but the type is different for each instance:

protected ComplexType _propertyName;
public ComplexType PropertyName
{
    get
    {
        if (_propertyName == null) {
            _propertyName = new ComplexType();
        }

        return _propertyName;
    }
}

To repeat this in C++ (as there are ~15 instances), I would have used a preprocessor macro but I notice C# doesn't support them.

I am wondering if anyone has a recommendation on how to do this cleanly in C#?


回答1:


This might make things a bit neater, you could add this method to introduce some reuse:

protected ComplexType _propertyName;
public ComplexType PropertyName
{
    get
    {
        return GetProperty(ref _propertyName);
    }
}
.
.
private T GetProperty<T>(ref T property) where T : new()
{
  if (property == null)
    property = new T();
  return property;
}



回答2:


You can use the ?? operator to simplify the code into one line:

protected ComplexType _propertyName;
public ComplexType PropertyName
{
  get
  {
    return _propertyName ?? (_propertyName = new ComplexType());
  }
}

As a side note I would probably avoid protected fields. If you need to set the property from a derived class I would rather create a protected setter.




回答3:


You can make a generic struct that handles the lazy creation:

public struct LazyCreate<T> where T : class, new() {
   private T _value;
   public T Value {
      get {
         if (_value == null) {
            _value = new T();
         }
         return _value;
      }
   }
}

protected LazyCreate<ComplexType> _propertyName;
public ComplexType PropertyName {
    get {
        return _propertyName.Value;
    }
}



回答4:


Even though it doesn't directly solve your problem, you could have a look at the new Lazy<T> class that ships with .NET 4.0. It is specifically designed for lazy initialization scenarios.




回答5:


You could use the much overlooked T4 (Text Template Transformation Toolkit) to generate the code. It is included with Visual Studio 2008.

There was a 2009-06 .NET Rocks episode about it: "Peter Vogel uses Code Generation".




回答6:


You could implement lazy initialization in a manner similar to this:

  public class Lazy<T> where T : new()
   {
       private T _value;
       private bool _isInitialized;

       private T GetValue()
       {
           if (!_isInitialized)
           {
               _value = new T();
               _isInitialized = true;
           }

           return _value;
       }

       public static implicit operator T (Lazy<T> t)
       {
           return t.GetValue();
       }
   }

which would allow you to write code like this:

      private Lazy<ComplexType> _lazyCt = new Lazy<ComplexType>();
      public ComplexType LazyCt
      {
          get { return _lazyCt; }
      }

The specifics of the initialization are irrelevant, I wrote it like this to show that you can make it transparently convertible to the non-lazy version, and perform the initialization on the first conversion. :)




回答7:


Try to use Hashtable or Dictionary <string, ComplexType> to group all properties. Something like this:

protected Dictionaty<string, ComplexType> _properties = new Dictionaty<string, ComplexType>();
public ComplexType Property(string name)
{
    get
    {
        if (!properties.ContainsKey(name))
            _properties[name] = new ComplexType();

        return __properties[name];
    }
}


来源:https://stackoverflow.com/questions/1388511/c-sharp-equivalent-for-c-macros-and-using-auto-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!