给C#auto属性一个初始值的最佳方法是什么?

给C#auto属性一个初始值的最佳方法是什么?,c#,constructor,getter,setter,automatic-properties,C#,Constructor,Getter,Setter,Automatic Properties,如何给C#auto属性一个初始值 我要么使用构造函数,要么恢复到旧语法 使用构造函数: class Person { public Person() { Name = "Initial Name"; } public string Name { get; set; } } 使用普通属性语法(带有初始值) 有更好的方法吗?您是否尝试过将or与构造函数结合使用?我觉得,如果要创建一个可能出现在设计器界面或属性网格中的类,则必须使用这两种方法之一。您

如何给C#auto属性一个初始值

我要么使用构造函数,要么恢复到旧语法

使用构造函数:

class Person 
{
    public Person()
    {
        Name = "Initial Name";
    }
    public string Name { get; set; }
}
使用普通属性语法(带有初始值)

有更好的方法吗?

您是否尝试过将or与构造函数结合使用?我觉得,如果要创建一个可能出现在设计器界面或属性网格中的类,则必须使用这两种方法之一。

您是否尝试过将or与构造函数结合使用?我觉得,如果要创建一个可能出现在设计器界面或属性网格中的类,这两种方法之一是必要的。

在C#5及更早版本中,要为自动实现的属性提供初始值,必须在构造函数中执行

由于C#6.0,您可以在线指定初始值。语法是:

public int X { get; set; } = x; // C# 6 or higher
用于VS设计器(或任何其他使用者)指定默认值,而不是初始值。(即使在设计对象中,初始值也是默认值)

编译时,
DefaultValueAttribute
不会影响生成的IL,也不会读取该IL以将属性初始化为该值(请参阅)

影响IL的属性示例有,…

在C#5及更早版本中,要为自动实现的属性提供初始值,必须在构造函数中执行

由于C#6.0,您可以在线指定初始值。语法是:

public int X { get; set; } = x; // C# 6 or higher
用于VS设计器(或任何其他使用者)指定默认值,而不是初始值。(即使在设计对象中,初始值也是默认值)

编译时,
DefaultValueAttribute
不会影响生成的IL,也不会读取该IL以将属性初始化为该值(请参阅)


影响IL的属性示例是,…

如果我不想在我的数据库中实际设置和持久化,有时我会使用此属性:

class Person
{
    private string _name; 
    public string Name 
    { 
        get 
        {
            return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
        } 

        set { _name = value; } 
    }
}
显然,如果它不是字符串,那么我可能会使对象为null(double?,int?),并检查它是否为null,返回默认值,或者返回它设置的值

然后,在保存之前,我可以在存储库中进行检查,以查看它是否为默认值且不持久,或者进行后门检入以查看支持值的真实状态


希望有帮助

如果我不想在我的数据库中实际设置并持久化它,有时我会使用它:

class Person
{
    private string _name; 
    public string Name 
    { 
        get 
        {
            return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
        } 

        set { _name = value; } 
    }
}
显然,如果它不是字符串,那么我可能会使对象为null(double?,int?),并检查它是否为null,返回默认值,或者返回它设置的值

然后,在保存之前,我可以在存储库中进行检查,以查看它是否为默认值且不持久,或者进行后门检入以查看支持值的真实状态


希望有帮助

就我个人而言,如果你不打算在汽车产业之外做任何事情,我根本不认为把它变成一个产业有什么意义。把它当作一块地就行了。这些项目的封装好处只是转移注意力,因为它们背后没有什么可封装的东西。如果您需要更改底层实现,您仍然可以自由地将它们重构为属性,而不会破坏任何依赖代码


嗯。。。也许这将是它自己稍后的问题的主题

就个人而言,如果你不打算做任何超出汽车产业之外的事情,我不认为把它变成一个产业有什么意义。把它当作一块地就行了。这些项目的封装好处只是转移注意力,因为它们背后没有什么可封装的东西。如果您需要更改底层实现,您仍然可以自由地将它们重构为属性,而不会破坏任何依赖代码


嗯。。。这可能是以后它自己的问题

当您为变量内联一个初始值时,它将在构造函数中隐式完成

我认为这种语法是C#5的最佳实践:

因为这使您可以清楚地控制分配的顺序值

从C#6开始,有一种新的方式:

public string Name { get; set; } = "Default Name";

当您内联变量的初始值时,它将在构造函数中隐式完成

我认为这种语法是C#5的最佳实践:

因为这使您可以清楚地控制分配的顺序值

从C#6开始,有一种新的方式:

public string Name { get; set; } = "Default Name";
在C#6及以上版本中,您只需使用以下语法:

public object Foo { get; set; } = bar;
请注意,要使用
只读
属性,只需省略集合,如下所示:

public object Foo { get; } = bar;
您还可以从构造函数中分配
只读
自动属性

在此之前,我的回答如下

我会避免在构造函数中添加默认值;将其保留为动态赋值,并避免在变量赋值时有两个点(即默认类型和构造函数中的类型)。在这种情况下,我通常只编写一个普通属性

另一个选项是执行ASP.Net的操作,并通过属性定义默认值:

在C#6及以上版本中,您只需使用以下语法:

public object Foo { get; set; } = bar;
请注意,要使用
只读
属性,只需省略集合,如下所示:

public object Foo { get; } = bar;
您还可以从构造函数中分配
只读
自动属性

在此之前,我的回答如下

我会避免在构造函数中添加默认值;将其保留为动态赋值,并避免在变量赋值时有两个点(即默认类型和构造函数中的类型)。在这种情况下,我通常只编写一个普通属性

另一个选项是执行ASP.Net的操作,并通过属性定义默认值:


小样本:

using System.ComponentModel;

private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
    get { return bShowGroup; }
    set { bShowGroup = value; }
}

小样本:

using System.ComponentModel;

private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
    get { return bShowGroup; }
    set { bShowGroup = value; }
}

于2015年1月2日编辑

C#6

有了C#6,您可以直接初始化自动属性(最后!),现在线程中还有其他的答案,可以
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InstanceAttribute : Attribute
{
    public bool IsConstructorCall { get; private set; }
    public object[] Values { get; private set; }
    public InstanceAttribute() : this(true) { }
    public InstanceAttribute(object value) : this(false, value) { }
    public InstanceAttribute(bool isConstructorCall, params object[] values)
    {
        IsConstructorCall = isConstructorCall;
        Values = values ?? new object[0];
    }
}
public abstract class DefaultValueInitializer
{
    protected DefaultValueInitializer()
    {
        InitializeDefaultValues(this);
    }

    public static void InitializeDefaultValues(object obj)
    {
        var props = from prop in obj.GetType().GetProperties()
                    let attrs = prop.GetCustomAttributes(typeof(InstanceAttribute), false)
                    where attrs.Any()
                    select new { Property = prop, Attr = ((InstanceAttribute)attrs.First()) };
        foreach (var pair in props)
        {
            object value = !pair.Attr.IsConstructorCall && pair.Attr.Values.Length > 0
                            ? pair.Attr.Values[0]
                            : Activator.CreateInstance(pair.Property.PropertyType, pair.Attr.Values);
            pair.Property.SetValue(obj, value, null);
        }
    }
}
public class Simple : DefaultValueInitializer
{
    [Instance("StringValue")]
    public string StringValue { get; set; }
    [Instance]
    public List<string> Items { get; set; }
    [Instance(true, 3,4)]
    public Point Point { get; set; }
}

public static void Main(string[] args)
{
    var obj = new Simple
        {
            Items = {"Item1"}
        };
    Console.WriteLine(obj.Items[0]);
    Console.WriteLine(obj.Point);
    Console.WriteLine(obj.StringValue);
}
Item1
(X=3,Y=4)
StringValue
private bool _SomeFlagSet = false;
public bool SomeFlag
{
    get
    {
        if (!_SomeFlagSet)
            SomeFlag = false;        

        return SomeFlag;
    }
    set
    {
        if (!_SomeFlagSet)
            _SomeFlagSet = true;

        SomeFlag = value;        
    }
}
public string Name { get; set; } = "Some Name";
public string Name { get; } = "Some Name";
public Class ClassName{
    public int PropName{get;set;}
    public ClassName{
        PropName=0;  //Default Value
    }
}
public class Coordinate
{ 
    public int X { get; set; } = 34; // get or set auto-property with initializer

    public int Y { get; } = 89;      // read-only auto-property with initializer

    public int Z { get; }            // read-only auto-property with no initializer
                                     // so it has to be initialized from constructor    

    public Coordinate()              // .ctor()
    {
        Z = 42;
    }
}
public class Person{

    public string FullName  => $"{First} {Last}"; // expression body notation

    public string First { get; set; } = "First";
    public string Last { get; set; } = "Last";
}
    var p = new Person();

    p.FullName; // First Last

    p.First = "Jon";
    p.Last = "Snow";

    p.FullName; // Jon Snow
public int ReadOnlyProp => 2;
public string PropTest { get; set; } = "test";
private string label = "Default Value";

// Expression-bodied get / set accessors.
public string Label
{
   get => label;
   set => this.label = value; 
 }
private string name;
public string Name 
{
    get 
    {
        if(name == null)
        {
            name = "Default Name";
        }
        return name;
    }
    set
    {
        name = value;
    }
}
public sealed  class Employee
{
    public int Id { get; set; } = 101;
}
//base class
public class Car
{
    public virtual string FuelUnits
    {
        get { return "gasoline in gallons"; }
        protected set { }
    }
}
//derived
public class Tesla : Car
{
    public override string FuelUnits => "ampere hour";
}
class Person 
{ 
    public string Name { get; init; } = "Anonymous user";
}
// 1. Person with default name
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
// > Hello, Anonymous user!


// 2. Person with assigned value
var me = new Person { Name = "@codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// > Hello, @codez0mb1e!


// 3. Attempt to re-assignment Name
me.Name = "My fake"; 
// > Compilation error: Init-only property can only be assigned in an object initializer