如何在方法或构造函数中为类的所有属性设置默认值?

时间:2017-09-07 14:36:13

标签: c# reflection types properties

所以,我希望有一个构造函数(或方法)将我的所有类属性设置为默认值。 到目前为止我到了这里:

class TestClass
{
    public enum MyEnum { En1, En2, En3}
    public string MyString { get; set; }
    public int MyInt { get; set; }
    public MyEnum MyEnums { get; set; }
    public TestClass()
    {
        var Properties = this.GetType().GetProperties();
        foreach (var Property in Properties)
        {
            Property.SetValue(this,default(Property.GetType()));
        }           
    }
}

我收到这个错误:“'属性'是一个变量但是像类型一样使用”(CS0118)。 我知道我可以为此目的使用struct。但实际上可以这样做吗?或者我必须为每个属性写一些像: MyString = default(string)MyInt = default(int) ......?

感谢您的任何建议:)

3 个答案:

答案 0 :(得分:0)

问题在于:

default(Property.GetType())

The default operator希望您为其提供类型,而不是Type类的实例。这有效,例如:

var x = default(String);

但这不是:

var y = default(typeof(String));

实际上你根本不需要做你正在做的事情。只保留默认值。编译器在构造函数执行时已经处理好了它。实际上,获取属性默认值的最简单方法是,在已知所有属性未被显式初始化的特定情况下,取其已有的任何值

Property.SetValue(this, Property.GetValue(this));

这没有任何意义:“让它成为现在的样子”。但这就是你的代码试图做的事情,因为每个属性已经具有的未初始化值是你希望分配给它的值。

添加大量旋转的代码,浪费时间,完全没有任何内容,这是一个坏主意。

但是如果你确实需要这样做(我不能过度强调你不这样做),你可以通过creating an uninitialized value of the correct type来做到这一点:

var type = Property.GetType();
var dflt = (type.IsValueType) 
               ? Activator.CreateInstance(type) 
               : null;
Property.SetValue(this, dflt);

答案 1 :(得分:0)

这是让任何属性都有默认值的一种方法:

class TestClass
    {
        private string _myString = "default";
        public string MyString {
            get {
                return _myString;
            }

            set {
                _myString = value;
            }
        }
    }

答案 2 :(得分:0)

正如其他人提到的那样,由于系统类型已经存在默认值,因此您的滑坡很滑。但是,如果你已经死定了说:“不,我希望字符串默认为null以外的其他东西并且是空的!”(我实际上是为了一个对于将空值移除到精神错乱点而疯狂的人)。我将分两部分来做,使它成为可选的并继承一个抽象类,可以在它的基础构造函数上调用它来使用反射来获取给定类型的所有对象。在我的例子中,我使用字符串。

基础示例:

public abstract class Base_Setter
{
  public Base_Setter() { }

  public Base_Setter(string overrideValue)
  {
    foreach (var property in GetType().GetProperties())
    {
      if(property.PropertyType == typeof(string))
      {
        property.SetValue(this, overrideValue);
      }
    }
  }
}

实施例:

public class Setter : Base_Setter
{
  public Setter() {}

  public Setter(string overrideValue) 
    : base(overrideValue)  { }

  public string Description { get; set; }
  public string Notes { get; set; }  
}

使用示例:

static void Main(string[] args)
{
  Setter usesSetup = new Setter(String.Empty);
  Setter usesNone = new Setter();

  Console.ReadLine();
}

然后,这会将给定类型的所有对象设置为您可以选择的特定设置。或者,如果你说:“这一切都很好,但我希望它硬编码只是做字符串清空”,你可以轻松地取出参数并修复它,或者制作另一个名为'AllStringEmptiesBase'或类似的基础。同样,这并不总是被推荐,但是如果你有一组巨大的POCO并希望使用巨大的画笔笔划确保它们都被设置为字符串为空,那么反射可能比一次一个更容易并且更新所有构造函数。另外,您可以通过继承在多个类上重复使用它。