c# - name - property get set default value




C#Auto-Property에 어떻게 기본값을 부여합니까? (15)

C # Auto-Property에 어떻게 기본값을 부여합니까? 나도 생성자를 사용하거나 이전 구문으로 되돌립니다.

생성자 사용 :

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

일반 속성 구문 사용 (기본값 사용)

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

더 좋은 방법이 있습니까?


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 # 5 및 이전 버전에서는 자동 구현 된 속성을 기본값으로 지정하기 위해 생성자에서이 속성을 수행해야합니다.

C # 6.0부터 자동 속성 초기화 프로그램을 사용할 수 있습니다. 구문은 다음과 같습니다.

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

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


initialize하기 위해 생성자를 사용하는 것은 나쁜 습관이고 나중에 더 많은 변경 사항을 초래할 것이다.


개인적으로, 나는 자동 재산 저쪽에 무언가를 전혀하지 않을 경우에 그것에게 재산을 만드는 점을 보지 않는다. 그냥 필드로 남겨주세요. 이 항목에 대한 캡슐화 이점은 캡슐화 할 수있는 요소가 없기 때문에 빨간색 청어입니다. 기본 구현을 변경해야하는 경우 종속 코드를 손상시키지 않고 속성을 그대로 리팩토링 할 수 있습니다.

흠 ... 어쩌면이 문제는 나중에 자신의 질문 일 것입니다.


내 솔루션 상수 또는 속성 형식 이니셜 라이저를 사용하여 기본 값 속성 초기화를 제공하는 사용자 지정 특성을 사용하는 것입니다.

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

이 속성을 사용하려면 특수 기본 class-initializer에서 클래스를 상속하거나 정적 도우미 메서드를 사용해야합니다.

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

다른 속성의 함수 로 기본 속성을 정의하고자 할 때, 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 accessor 키워드를 사용하지 않아야합니다.

MSDN 에 대한 세부 정보


명확히하기 위해, 예, 클래스 파생 오브젝트의 생성자에 기본값을 설정해야합니다. 사용되는 경우 생성을 위해 적절한 액세스 수정자를 사용하여 생성자가 존재하는지 확인해야합니다. 객체가 인스턴스화되어 있지 않은 경우, 즉 생성자가없는 경우 (정적 메소드 등), 필드에 의해 디폴트 치를 설정할 수 있습니다. 여기서 추론하는 것은 객체 자체가 단 한 번만 생성되고 인스턴스화하지 않는다는 것입니다.

@ 대런 Kopp - 좋은 대답, 깨끗하고 올바른. 다시 말하자면 추상 메소드의 생성자를 작성할 수 있습니다. 생성자를 작성할 때 기본 클래스에서 액세스해야합니다.

기본 클래스의 생성자 :

public BaseClassAbstract()
{
    this.PropertyName = "Default Name";
}

파생 / 콘크리트 / 하위 클래스의 생성자 :

public SubClass() : base() { }

요점은 기본 클래스에서 가져온 인스턴스 변수가 기본 필드 이름을 묻을 수 있다는 것입니다. "this"를 사용하여 현재 인스턴스화 된 객체 값을 설정합니다. 현재 인스턴스 및 인스턴스화 할 필수 권한 수준 (액세스 한정자)과 관련하여 개체를 올바르게 구성 할 수 있습니다.


변수의 초기 값을 인라인하면 어쨌든 생성자에서 암시 적으로 수행됩니다.

나는이 구문이 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"


약간의 완전한 샘플 :

using System.ComponentModel;

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


class Person 
{    
    /// Gets/sets a value indicating whether auto 
    /// save of review layer is enabled or not
    [System.ComponentModel.DefaultValue(true)] 
    public bool AutoSaveReviewLayer { get; set; }
}

public Class ClassName{
    public int PropName{get;set;}
    public ClassName{
        PropName=0;  //Default Value
    }
}




automatic-properties