System.FlagsAttribute sınıfı
Bu makale, bu API'nin başvuru belgelerine ek açıklamalar sağlar.
FlagsAttribute özniteliği, bir numaralandırmanın bit alanı olarak, yani bir bayrak kümesi olarak ele alınabileceğini gösterir.
Bit alanları genellikle birlikte gerçekleşebilecek öğe listeleri için kullanılırken, numaralandırma sabitleri genellikle birbirini dışlayan öğelerin listeleri için kullanılır. Bu nedenle, bit alanları adsız değerler oluşturmak için bit düzeyinde OR
bir işlemle birleştirilecek şekilde tasarlanmıştır, ancak numaralandırılmış sabitler değildir. Diller, sabit listesi sabitlerine kıyasla bit alanlarının kullanımında farklılık gösterir.
FlagsAttribute Öznitelikleri
AttributeUsageAttribute bu sınıfa uygulanır ve Inherited özelliği belirtir false
. Bu öznitelik yalnızca numaralandırmalara uygulanabilir.
FlagsAttribute ve sabit listesi yönergeleri
FlagsAttribute Numaralandırma için özel özniteliği yalnızca bit düzeyinde bir işlem (AND, OR, EXCLUSIVE OR) sayısal bir değer üzerinde gerçekleştirilecekse kullanın.
Numaralandırma sabitlerini iki, yani 1, 2, 4, 8 vb. güçlerinde tanımlayın. Bu, birleştirilmiş sabit listesi sabitlerindeki tek tek bayrakların çakışmadığı anlamına gelir.
Yaygın olarak kullanılan bayrak bileşimleri için numaralandırılmış sabit oluşturmayı göz önünde bulundurun. Örneğin, ve sabitlerini içeren dosya G/Ç işlemleri için kullanılan bir numaralandırmanız varsa ve
Write
Write = 2
bayraklarınıRead = 1
Read
birleştiren numaralandırılmış sabitiReadWrite = Read OR Write
oluşturmayı göz önünde bulundurun. Ayrıca, bayrakları birleştirmek için kullanılan bit düzeyinde OR işlemi, bazı durumlarda basit görevler için gerekli olmaması gereken gelişmiş bir kavram olarak kabul edilebilir.Birçok bayrak konumu 1 olarak ayarlanabileceği için negatif bir sayıyı bayrak numaralandırılmış sabiti olarak tanımlarsanız dikkatli olun; bu durum kodunuzu kafa karıştırıcı hale getirebilir ve kodlama hatalarını teşvik edebilir.
Bir bayrağın sayısal değerde ayarlanıp ayarlanmadığını test etmenin kullanışlı bir yolu, sayısal değer ile bayrak numaralandırılmış sabiti arasında bit düzeyinde AND işlemi gerçekleştirmektir. Bu işlem, sayısal değerdeki tüm bitleri bayrakla eşleşmeyen sıfıra ayarlar ve ardından bu işlemin sonucunun bayrak numaralandırılmış sabitine eşit olup olmadığını test eder.
Değeri sıfır olan numaralandırılmış bayrak sabitinin adı olarak kullanın
None
. Sonuç her zaman sıfır olduğundan bir bayrağı test etmek için bit düzeyinde AND işleminde numaralandırılmış sabiti kullanamazsınızNone
. Ancak, sayısal değerdeki herhangi bir bitin ayarlanıp ayarlanmadığını belirlemek için sayısal değer ileNone
numaralandırılmış sabit arasında bit düzeyinde değil mantıksal bir karşılaştırma gerçekleştirebilirsiniz.Bayrak numaralandırması yerine bir değer sabit listesi oluşturursanız, yine de numaralandırılmış sabit
None
oluşturmak faydalı olabilir. Bunun nedeni, numaralandırma için kullanılan belleğin varsayılan olarak ortak dil çalışma zamanı tarafından sıfıra başlatılmasıdır. Sonuç olarak, değeri sıfır olan bir sabit tanımlamazsanız, sabit listesi oluşturulduğunda geçersiz bir değer içerir.Uygulamanızın temsil etmesi gereken belirgin bir varsayılan durum varsa, varsayılanı temsil etmek için değeri sıfır olan numaralandırılmış sabiti kullanmayı göz önünde bulundurun. Varsayılan bir durum yoksa, değeri sıfır olan, diğer numaralandırılmış sabitlerden herhangi biri tarafından temsil edilmeyen büyük/küçük harf anlamına gelen numaralandırılmış sabit kullanmayı göz önünde bulundurun.
Numaralandırma değerini yalnızca numaralandırmanın durumunu yansıtacak şekilde tanımlamayın. Örneğin, yalnızca numaralandırmanın sonunu işaretleyen bir numaralandırılmış sabit tanımlamayın. Numaralandırmanın son değerini belirlemeniz gerekiyorsa, bu değeri açıkça denetleyin. Ayrıca, aralıktaki tüm değerler geçerliyse ilk ve son numaralandırılmış sabit için aralık denetimi gerçekleştirebilirsiniz.
Gelecekte kullanmak üzere ayrılmış numaralandırılmış sabitler belirtmeyin.
Numaralandırılmış sabiti değer olarak alan bir yöntem veya özellik tanımlarken, değeri doğrulamayı göz önünde bulundurun. Bunun nedeni, bu sayısal değer numaralandırmada tanımlanmamış olsa bile numaralandırma türüne sayısal bir değer atamanızdır.
Örnekler
Aşağıdaki örnek, özniteliğin FlagsAttribute
kullanımını gösterir ve bir Enum bildirim üzerinde kullanma FlagsAttribute
yöntemi üzerindeki ToString etkisini gösterir.
using System;
class Example
{
// Define an Enum without FlagsAttribute.
enum SingleHue : short
{
None = 0,
Black = 1,
Red = 2,
Green = 4,
Blue = 8
};
// Define an Enum with FlagsAttribute.
[Flags]
enum MultiHue : short
{
None = 0,
Black = 1,
Red = 2,
Green = 4,
Blue = 8
};
static void Main()
{
// Display all possible combinations of values.
Console.WriteLine(
"All possible combinations of values without FlagsAttribute:");
for (int val = 0; val <= 16; val++)
Console.WriteLine("{0,3} - {1:G}", val, (SingleHue)val);
// Display all combinations of values, and invalid values.
Console.WriteLine(
"\nAll possible combinations of values with FlagsAttribute:");
for (int val = 0; val <= 16; val++)
Console.WriteLine("{0,3} - {1:G}", val, (MultiHue)val);
}
}
// The example displays the following output:
// All possible combinations of values without FlagsAttribute:
// 0 - None
// 1 - Black
// 2 - Red
// 3 - 3
// 4 - Green
// 5 - 5
// 6 - 6
// 7 - 7
// 8 - Blue
// 9 - 9
// 10 - 10
// 11 - 11
// 12 - 12
// 13 - 13
// 14 - 14
// 15 - 15
// 16 - 16
//
// All possible combinations of values with FlagsAttribute:
// 0 - None
// 1 - Black
// 2 - Red
// 3 - Black, Red
// 4 - Green
// 5 - Black, Green
// 6 - Red, Green
// 7 - Black, Red, Green
// 8 - Blue
// 9 - Black, Blue
// 10 - Red, Blue
// 11 - Black, Red, Blue
// 12 - Green, Blue
// 13 - Black, Green, Blue
// 14 - Red, Green, Blue
// 15 - Black, Red, Green, Blue
// 16 - 16
open System
// Define an Enum without FlagsAttribute.
type SingleHue =
| None = 0
| Black = 1
| Red = 2
| Green = 4
| Blue = 8
// Define an Enum with FlagsAttribute.
[<Flags>]
type MultiHue =
| None = 0
| Black = 1
| Red = 2
| Green = 4
| Blue = 8
// Display all possible combinations of values.
printfn "All possible combinations of values without FlagsAttribute:"
for i = 0 to 16 do
printfn $"{i,3} - {enum<SingleHue> i:G}"
// Display all combinations of values, and invalid values.
printfn "\nAll possible combinations of values with FlagsAttribute:"
for i = 0 to 16 do
printfn $"{i,3} - {enum<MultiHue> i:G}"
// The example displays the following output:
// All possible combinations of values without FlagsAttribute:
// 0 - None
// 1 - Black
// 2 - Red
// 3 - 3
// 4 - Green
// 5 - 5
// 6 - 6
// 7 - 7
// 8 - Blue
// 9 - 9
// 10 - 10
// 11 - 11
// 12 - 12
// 13 - 13
// 14 - 14
// 15 - 15
// 16 - 16
//
// All possible combinations of values with FlagsAttribute:
// 0 - None
// 1 - Black
// 2 - Red
// 3 - Black, Red
// 4 - Green
// 5 - Black, Green
// 6 - Red, Green
// 7 - Black, Red, Green
// 8 - Blue
// 9 - Black, Blue
// 10 - Red, Blue
// 11 - Black, Red, Blue
// 12 - Green, Blue
// 13 - Black, Green, Blue
// 14 - Red, Green, Blue
// 15 - Black, Red, Green, Blue
// 16 - 16
Module Example
' Define an Enum without FlagsAttribute.
Enum SingleHue As Short
None = 0
Black = 1
Red = 2
Green = 4
Blue = 8
End Enum
' Define an Enum with FlagsAttribute.
<Flags()>
Enum MultiHue As Short
None = 0
Black = 1
Red = 2
Green = 4
Blue = 8
End Enum
Sub Main()
' Display all possible combinations of values.
Console.WriteLine(
"All possible combinations of values without FlagsAttribute:")
For val As Integer = 0 To 16
Console.WriteLine("{0,3} - {1:G}", val, CType(val, SingleHue))
Next
Console.WriteLine()
' Display all combinations of values, and invalid values.
Console.WriteLine(
"All possible combinations of values with FlagsAttribute:")
For val As Integer = 0 To 16
Console.WriteLine( "{0,3} - {1:G}", val, CType(val, MultiHue))
Next
End Sub
End Module
' The example displays the following output:
' All possible combinations of values without FlagsAttribute:
' 0 - None
' 1 - Black
' 2 - Red
' 3 - 3
' 4 - Green
' 5 - 5
' 6 - 6
' 7 - 7
' 8 - Blue
' 9 - 9
' 10 - 10
' 11 - 11
' 12 - 12
' 13 - 13
' 14 - 14
' 15 - 15
' 16 - 16
'
' All possible combinations of values with FlagsAttribute:
' 0 - None
' 1 - Black
' 2 - Red
' 3 - Black, Red
' 4 - Green
' 5 - Black, Green
' 6 - Red, Green
' 7 - Black, Red, Green
' 8 - Blue
' 9 - Black, Blue
' 10 - Red, Blue
' 11 - Black, Red, Blue
' 12 - Green, Blue
' 13 - Black, Green, Blue
' 14 - Red, Green, Blue
' 15 - Black, Red, Green, Blue
' 16 - 16
Yukarıdaki örnek, SingleHue
renkle ilgili iki numaralandırmayı ve MultiHue
tanımlar. İkincisi özniteliğine FlagsAttribute
sahiptir; önceki özniteliği yoktur. Örnek, sabit listesi türünün temel değerlerini temsil etmeyen tamsayılar da dahil olmak üzere bir tamsayı aralığının numaralandırma türüne atanması ve bunların dize gösterimlerinin görüntülenmesindeki davranış farkını gösterir. Örneğin, 3 herhangi SingleHue
bir üyenin temel değeri olmadığından 3 değerinin bir SingleHue
değer olarak temsil edilemeyeceğini, özniteliği ise FlagsAttribute
3 MultiHue
değerinin Black, Red
temsil edilemediğini unutmayın.
Aşağıdaki örnek özniteliğiyle FlagsAttribute
başka bir numaralandırma tanımlar ve bir veya daha fazla bit alanının sabit listesi değerinde ayarlanıp ayarlanmadığını belirlemek için bit düzeyinde mantıksal ve eşitlik işleçlerinin nasıl kullanılacağını gösterir. Bunu yapmak için yöntemini de kullanabilirsiniz Enum.HasFlag , ancak bu örnekte gösterilmez.
using System;
[Flags]
public enum PhoneService
{
None = 0,
LandLine = 1,
Cell = 2,
Fax = 4,
Internet = 8,
Other = 16
}
public class Example1
{
public static void Main()
{
// Define three variables representing the types of phone service
// in three households.
var household1 = PhoneService.LandLine | PhoneService.Cell |
PhoneService.Internet;
var household2 = PhoneService.None;
var household3 = PhoneService.Cell | PhoneService.Internet;
// Store the variables in an array for ease of access.
PhoneService[] households = { household1, household2, household3 };
// Which households have no service?
for (int ctr = 0; ctr < households.Length; ctr++)
Console.WriteLine("Household {0} has phone service: {1}",
ctr + 1,
households[ctr] == PhoneService.None ?
"No" : "Yes");
Console.WriteLine();
// Which households have cell phone service?
for (int ctr = 0; ctr < households.Length; ctr++)
Console.WriteLine("Household {0} has cell phone service: {1}",
ctr + 1,
(households[ctr] & PhoneService.Cell) == PhoneService.Cell ?
"Yes" : "No");
Console.WriteLine();
// Which households have cell phones and land lines?
var cellAndLand = PhoneService.Cell | PhoneService.LandLine;
for (int ctr = 0; ctr < households.Length; ctr++)
Console.WriteLine("Household {0} has cell and land line service: {1}",
ctr + 1,
(households[ctr] & cellAndLand) == cellAndLand ?
"Yes" : "No");
Console.WriteLine();
// List all types of service of each household?//
for (int ctr = 0; ctr < households.Length; ctr++)
Console.WriteLine("Household {0} has: {1:G}",
ctr + 1, households[ctr]);
Console.WriteLine();
}
}
// The example displays the following output:
// Household 1 has phone service: Yes
// Household 2 has phone service: No
// Household 3 has phone service: Yes
//
// Household 1 has cell phone service: Yes
// Household 2 has cell phone service: No
// Household 3 has cell phone service: Yes
//
// Household 1 has cell and land line service: Yes
// Household 2 has cell and land line service: No
// Household 3 has cell and land line service: No
//
// Household 1 has: LandLine, Cell, Internet
// Household 2 has: None
// Household 3 has: Cell, Internet
open System
[<Flags>]
type PhoneService =
| None = 0
| LandLine = 1
| Cell = 2
| Fax = 4
| Internet = 8
| Other = 16
// Define three variables representing the types of phone service
// in three households.
let household1 =
PhoneService.LandLine ||| PhoneService.Cell ||| PhoneService.Internet
let household2 =
PhoneService.None
let household3 =
PhoneService.Cell ||| PhoneService.Internet
// Store the variables in a list for ease of access.
let households =
[ household1; household2; household3 ]
// Which households have no service?
for i = 0 to households.Length - 1 do
printfn $"""Household {i + 1} has phone service: {if households[i] = PhoneService.None then "No" else "Yes"}"""
printfn ""
// Which households have cell phone service?
for i = 0 to households.Length - 1 do
printfn $"""Household {i + 1} has cell phone service: {if households[i] &&& PhoneService.Cell = PhoneService.Cell then "Yes" else "No"}"""
printfn ""
// Which households have cell phones and land lines?
let cellAndLand =
PhoneService.Cell ||| PhoneService.LandLine
for i = 0 to households.Length - 1 do
printfn $"""Household {i + 1} has cell and land line service: {if households[i] &&& cellAndLand = cellAndLand then "Yes" else "No"}"""
printfn ""
// List all types of service of each household?//
for i = 0 to households.Length - 1 do
printfn $"Household {i + 1} has: {households[i]:G}"
// The example displays the following output:
// Household 1 has phone service: Yes
// Household 2 has phone service: No
// Household 3 has phone service: Yes
//
// Household 1 has cell phone service: Yes
// Household 2 has cell phone service: No
// Household 3 has cell phone service: Yes
//
// Household 1 has cell and land line service: Yes
// Household 2 has cell and land line service: No
// Household 3 has cell and land line service: No
//
// Household 1 has: LandLine, Cell, Internet
// Household 2 has: None
// Household 3 has: Cell, Internet
<Flags()>
Public Enum PhoneService As Integer
None = 0
LandLine = 1
Cell = 2
Fax = 4
Internet = 8
Other = 16
End Enum
Module Example1
Public Sub Main()
' Define three variables representing the types of phone service
' in three households.
Dim household1 As PhoneService = PhoneService.LandLine Or
PhoneService.Cell Or
PhoneService.Internet
Dim household2 As PhoneService = PhoneService.None
Dim household3 As PhoneService = PhoneService.Cell Or
PhoneService.Internet
' Store the variables in an array for ease of access.
Dim households() As PhoneService = { household1, household2,
household3 }
' Which households have no service?
For ctr As Integer = 0 To households.Length - 1
Console.WriteLine("Household {0} has phone service: {1}",
ctr + 1,
If(households(ctr) = PhoneService.None,
"No", "Yes"))
Next
Console.WriteLine()
' Which households have cell phone service?
For ctr As Integer = 0 To households.Length - 1
Console.WriteLine("Household {0} has cell phone service: {1}",
ctr + 1,
If((households(ctr) And PhoneService.Cell) = PhoneService.Cell,
"Yes", "No"))
Next
Console.WriteLine()
' Which households have cell phones and land lines?
Dim cellAndLand As PhoneService = PhoneService.Cell Or PhoneService.LandLine
For ctr As Integer = 0 To households.Length - 1
Console.WriteLine("Household {0} has cell and land line service: {1}",
ctr + 1,
If((households(ctr) And cellAndLand) = cellAndLand,
"Yes", "No"))
Next
Console.WriteLine()
' List all types of service of each household?'
For ctr As Integer = 0 To households.Length - 1
Console.WriteLine("Household {0} has: {1:G}",
ctr + 1, households(ctr))
Next
Console.WriteLine()
End Sub
End Module
' The example displays the following output:
' Household 1 has phone service: Yes
' Household 2 has phone service: No
' Household 3 has phone service: Yes
'
' Household 1 has cell phone service: Yes
' Household 2 has cell phone service: No
' Household 3 has cell phone service: Yes
'
' Household 1 has cell and land line service: Yes
' Household 2 has cell and land line service: No
' Household 3 has cell and land line service: No
'
' Household 1 has: LandLine, Cell, Internet
' Household 2 has: None
' Household 3 has: Cell, Internet