• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

为 C# 自动属性赋予初始值的最佳方法是什么意思

武飞扬头像
HuntsBot
帮助1

问:

如何为 C# 自动属性赋予初始值?

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

使用构造函数:

class Person 
{
    public Person()
    {
        Name = "Initial Name";
    }
    public string Name { get; set; }
}

使用普通属性语法(带有初始值)

private string name = "Initial Name";
public string Name 
{
    get 
    {
        return name;
    }
    set
    {
        name = value;
    }
}

有没有更好的办法?

答1:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

在 C# 5 及更早版本中,要为自动实现的属性赋予初始值,您必须在构造函数中进行。

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

public int X { get; set; } = x; // C# 6 or higher

DefaultValueAttribute 旨在供 VS 设计者(或任何其他使用者)用于指定默认值,而不是初始值。 (即使在设计对象中,初始值也是默认值)。

在编译时,DefaultValueAttribute 不会影响生成的 IL,并且不会读取它来将属性初始化为该值(请参阅 DefaultValue attribute is not working with my Auto Property)。

影响 IL 的属性示例有 ThreadStaticAttribute、CallerMemberNameAttribute、…

值得注意的是,这也适用于 getter-only 属性:public int X { get; } = x;

答2:

huntsbot.com聚合了超过10 全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

于 15 年 1 月 2 日编辑

C# 6:

使用 C# 6,您可以直接初始化自动属性(终于!),现在还有其他答案可以描述这一点。

C# 5 及以下:

尽管该属性的预期用途不是实际设置属性的值,但您可以使用反射来始终设置它们…

public class DefaultValuesTest
{    
    public DefaultValuesTest()
    {               
        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
        {
            DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];

            if (myAttribute != null)
            {
                property.SetValue(this, myAttribute.Value);
            }
        }
    }

    public void DoTest()
    {
        var db = DefaultValueBool;
        var ds = DefaultValueString;
        var di = DefaultValueInt;
    }


    [System.ComponentModel.DefaultValue(true)]
    public bool DefaultValueBool { get; set; }

    [System.ComponentModel.DefaultValue("Good")]
    public string DefaultValueString { get; set; }

    [System.ComponentModel.DefaultValue(27)]
    public int DefaultValueInt { get; set; }
}

学新通

投票 -1:充其量,它看起来主观上看起来比在构造函数中初始化更整洁。这样做的代价是让刚接触代码库的开发人员感到困惑,性能更差,语义上改变了内置属性的含义,只允许常量,在多个属性中很难发现默认值,必须记住在每个构造函数重载时运行它,并且有可能在属性和构造函数中定义默认值。

答3:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

当您内联变量的初始值时,无论如何它都会在构造函数中隐式完成。

我认为这种语法是 C# 中的最佳实践,最高可达 5:

class Person 
{
    public Person()
    {
        //do anything before variable assignment

        //assign initial values
        Name = "Default Name";

        //do anything after variable assignment
    }
    public string Name { get; set; }
}

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

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

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

答4:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

有时我会使用它,如果我不希望它被实际设置并保留在我的数据库中:

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

        set { _name = value; } 
    }
}

显然,如果它不是字符串,那么我可以使对象为空(double?, int?)并检查它是否为空,返回一个默认值,或者返回它设置的值。

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

希望有帮助!

return _name ?? "Default Name"; 可能更清楚的是,您的

@abatishchev:虽然那不一样。如果字符串为“”或为空,坩埚代码将返回“默认名称”,但使用您的方法将仅在它为空的情况下返回“默认名称”。此外,是否“??”也可以讨论。或“IsNullOrEmpty”更清楚。

该点是默认值,因此可以为空的检查会破坏该点。基思的回答通过在 Tor 中初始化它来证明这一点。如果是针对分贝,我并没有真正看到与拥有默认列值并使其成为非空列的区别,无论类字段的数量如何,这都会更有效。我不会投反对票,但敦促开发人员考虑这一点,而不是在您的财产程序中使用空/空支票。

为了澄清每次调用类属性时,它都会进行空/空检查,因为 dB 只会在通常占 dB 工作 20% 的 INSERT 或 UPDATE 上执行此操作。相反,可能每个字符串属性都有一个额外的调用,这是对 CPU 周期的浪费,恕我直言,这是一个糟糕的设计选择。另外,现在有 Null Ref Type,因此处理 nullable 更为常见。

答5:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

在 C# 6.0 中,这是轻而易举的事!

您可以在 Class 声明本身的属性声明语句中执行此操作。

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;
    }
}

我还没有 C#6.0,并且正在检查我需要哪个版本来获取自动属性的默认值。 C# 6.0 是否也不需要使用 { get; set; } 或 { get; private set; } 否则设置值会被编译器阻止?

答6:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

从 C# 6.0 开始,我们可以为自动实现的属性分配默认值。

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

我们还可以创建只读的自动实现属性,例如:

public string Name { get; } = "Some Name";

请参阅:C# 6: First reactions , Initializers for automatically implemented properties - By Jon Skeet

答7:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

在 C# (6.0) 及更高版本中,您可以执行以下操作:

对于只读属性

public int ReadOnlyProp => 2;

对于可写和可读属性

public string PropTest { get; set; } = "test";

在当前版本的 C# (7.0) 中,您可以执行以下操作:(该片段显示了如何使用表达式主体的 get/set 访问器来使与支持字段一起使用时更紧凑)

private string label = "Default Value";

// Expression-bodied get / set accessors.
public string Label
{
   get => label;
   set => this.label = value; 
 }

此外,请考虑示例 class C { public DateTime P { get; } = DateTime.Now; public DateTime Q => DateTime.Now; },其中属性 P 和 Q 都只有一个 getter,但 P 和 Q 的行为非常不同!

答8:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

在 C# 9.0 中是 init 关键字的 added support - 非常有用且极其复杂的方式用于声明只读自动属性:

宣布:

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

学新通

以前我们可以只使用 public string Name { get; } = "Anonymous user";,版本 9 实现对于增加您仍然可以设置值的范围更有用。这个答案表明我们必须等待 C# 9,这对于 OP 的预期行为是不正确的。

答9:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

除了已经接受的答案之外,对于想要将默认属性定义为其他属性的函数的场景,您可以在 C#6.0(及更高版本)上使用表达式主体表示法以获得更优雅和简洁的构造,例如:

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

为了能够使用上述“=>”表示法,该属性必须是只读的,并且您不要使用 get 访问器关键字。

MSDN 的详细信息

答10:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

在 C# 6 及更高版本中,您可以简单地使用以下语法:

public object Foo { get; set; } = bar;

请注意,要具有 readonly 属性,只需省略该集合,如下所示:

public object Foo { get; } = bar;

您还可以从构造函数分配 readonly 自动属性。

在此之前,我的回答如下。

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

另一种选择是做 ASP.Net 所做的事情并通过属性定义默认值:

http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

哇,这是过去的爆炸。我似乎记得这是基于对规范的阅读(这里的部分摘录:msdn.microsoft.com/en-us/library/aa645756(v=vs.71).aspx)。考虑到版本(和 Roslyn)的时间和数量,这很可能不再是这种情况。虽然反击将不胜感激。

无论您是使用初始值还是在构造函数中赋值,默认赋值都会自动发生。存在细微的语义差异 - 字段分配发生在构造函数调用之前 - 但 null 分配仍然会发生。请参阅 10.4.5“所有实例字段...首先初始化为其默认值,然后执行实例字段初始化程序”msdn.microsoft.com/en-us/library/aa645757(VS.71).aspx

答11:

huntsbot.com – 高效赚钱,自由工作

我的解决方案是使用自定义属性,通过常量或使用属性类型初始化程序提供默认值属性初始化。

[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 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

如上所述,使用反射来初始化默认值既慢又过分。在构造函数上初始化,使用非自动属性或在 c# 6 及更高版本上,使用已接受答案中显示的简化符号

什么时候使用它比此处所述的其他选项更好?

原文链接:https://www.huntsbot.com/qa/Zv4Y/what-is-the-best-way-to-give-a-c-sharp-auto-property-an-initial-value?lang=zh_CN&from=csdn

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhghegkf
系列文章
更多 icon
同类精品
更多 icon
继续加载