c# getter setter
你如何給C#自動屬性一個默認值? (15)
你如何給C#自動屬性一個默認值? 我要么使用構造函數,要么恢復到舊的語法。
使用構造函數:
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;
}
}
DefaultValueAttribute只能在vs設計器中工作。 它不會將該屬性初始化為該值。
一點完整的樣品:
using System.ComponentModel;
private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
get { return bShowGroup; }
set { bShowGroup = value; }
}
使用構造函數是因為“當構造函數完成時,施工應該完成”。 屬性就像你的類所持有的狀態,如果你必須初始化一個默認狀態,你可以在你的構造函數中這樣做。
在C#(6.0)及更高版本中 ,您可以執行以下操作:
用於Readonly屬性
public int ReadOnlyProp => 2;
對於Writable和Readable屬性
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;
}
在C#5及更早版本中,為了賦予自動實現的屬性默認值,您必須在構造函數中完成。
自C#6.0以來,包含了自動屬性初始值設定項的功能。 語法是:
public int X { get; set; } = x; // C# 6 or higher
在構造函數中。 構造函數的目的是初始化它的數據成員。
就我個人而言,如果除了汽車財產之外不會做任何事情,我根本看不出把它變成財產的問題。 只要把它作為一個領域。 這些項目的封裝優勢只是紅鯡魚,因為它們背後沒有任何封裝。 如果您需要更改底層實現,您仍然可以自由地將它們重構為屬性,而不會破壞任何相關代碼。
嗯......也許這將成為它後面自己問題的主題
我的解決方案是使用自定義屬性,通過常量或使用屬性類型初始值設定項提供默認值屬性初始化。
[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
我認為這樣做會為你帶來SomeFlag默認值為false。
private bool _SomeFlagSet = false;
public bool SomeFlag
{
get
{
if (!_SomeFlagSet)
SomeFlag = false;
return SomeFlag;
}
set
{
if (!_SomeFlagSet)
_SomeFlagSet = true;
SomeFlag = value;
}
}
澄清,是的,你需要在類派生對象的構造函數中設置默認值。 您將需要確保構造函數存在與正確的訪問修飾符在建築使用。 如果對像沒有實例化,例如它沒有構造函數(例如靜態方法),那麼可以通過該字段設置默認值。 這裡的推理是對象本身只會被創建一次,並且你沒有實例化它。
@Darren Kopp - 很好的答案,乾淨,正確。 並且要重申,您可以為抽象方法編寫構造函數。 編寫構造函數時,只需從基類訪問它們即可:
基類的構造函數:
public BaseClassAbstract()
{
this.PropertyName = "Default Name";
}
Derived / Concrete / Sub-Class的構造函數:
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"
除了已經接受的答案之外,對於想要將默認屬性定義為其他屬性的函數時 ,您可以在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詳細信息
類型道具和按下按鈕“選項卡”和Visual Studio建議您遵循代碼,
public int MyProperty { get; set; }
在您可以更改修飾符,數據類型,名稱並輕鬆分配設置並獲取值後。
如果你需要在另一個類中使用一些變量 ,
public static int MyProperty { get; set; }
在代碼中,您可以分配變量
MyProperty=1;
在另一個課程中你可以使用這個,
MessageBox.Show(Classname.MyProperty);
public Class ClassName{
public int PropName{get;set;}
public ClassName{
PropName=0; //Default Value
}
}