

'.NET > C#' 카테고리의 다른 글
Concurrency - Asynchronous Programming (0) | 2023.08.16 |
---|---|
Concurrency (동시성) (0) | 2023.08.16 |
Array Marshaling (0) | 2021.10.15 |
Comparisons and Sorts (0) | 2021.10.15 |
Debugging Tips (0) | 2021.09.15 |
Concurrency - Asynchronous Programming (0) | 2023.08.16 |
---|---|
Concurrency (동시성) (0) | 2023.08.16 |
Array Marshaling (0) | 2021.10.15 |
Comparisons and Sorts (0) | 2021.10.15 |
Debugging Tips (0) | 2021.09.15 |
C++
HRESULT New1(int ar[10]); HRESULT New2(double ar[10][20]); HRESULT New3(LPWStr ar[10]);
C#
void New1([MarshalAs(UnmanagedType.LPArray, SizeConst=10)] int[] ar); void New2([MarshalAs(UnmanagedType.LPArray, SizeConst=200)] double[] ar); void New2([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeConst=10)] String[] ar);
C++
HRESULT New1(int ar[]); HRESULT New2(int ArSize, [size_is(ArSize)] double ar[]); HRESULT New3(int ElemCnt, [length_is(ElemCnt)] LPStr ar[]);
C#
void New1(ref int ar); void New2(ref double ar); void New3(ref String ar);
배열의 요소 수를 지정하는 방법
1. 배열의 요소 수가 포함된 또 다른 매개 변수 식별, 매개 변수는 위치로 식별
void New( int ElemCnt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int[] ar);
2. 배열의 크기를 상수로 정의
void New( [MarshalAs(UnmanagedType.LPArray, SizeConst=128)] int[] ar);
구조체 내의 배열
C++
struct MyStruct { int values[128]; };
C#
[StructLayout(LayoutKind.Sequential)] public struct MyStruct { [MarshalAs(UnmanagedType.ByValArray, SizeConstant = 128)] public int[] values; }
struct Image { unsigned char* image_ptr; int rows; int cols; }; typedef void (*pfnCallback)(bool[], const char* [], Image[], Image, int length);
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Image { public IntPtr image_ptr; public int rows; public int cols; } public delegate void dgCallback( [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 4)] bool[] status, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 4)] string[] id, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] Image[] img_face, Image img_org, int length);
Concurrency (동시성) (0) | 2023.08.16 |
---|---|
Marshaling: 복사 및 고정 (0) | 2021.10.15 |
Comparisons and Sorts (0) | 2021.10.15 |
Debugging Tips (0) | 2021.09.15 |
Equals, IEquatable<T> (0) | 2021.08.15 |
Comparisons and Sorts Within Collections
Do comparisons & sorts using the System.Collections classes in .NET, which help in finding an element to remove or returning the value of a key-and-value pair.
docs.microsoft.com
If the collection is generic, then items are compared for equality according to the following guidelines:
In addition, some constructor overloads for dictionary collections an IEqualityComparer<T> implementation,
which is used to compare keys for equality.
We recommend that you derive from the EqualityComparer<T> class instead of implementing the IEqualityComparer<T> interface, because the EqualityComparer<T> class tests for equality using the IEquatable<T>.Equals method instead of the Object.Equals method.
For comparing objects, there is the concept of a default comparer and an explicit comparer.
The default comparer relies on at least one of the objects being compared to implement the IComparable interface.
For a generic collection, equality comparison is determined according to the following:
Example:
using System; using System.Collections.Generic; // Simple business object. A PartId is used to identify the // type of part but the part name can change. public class Part : IEquatable<Part>, IComparable<Part> { public string PartName { get; set; } public int PartId { get; set; } public override string ToString() => $"ID: {PartId} Name: {PartName}"; public override bool Equals(object obj) => (obj is Part part) ? Equals(part) : false; public int SortByNameAscending(string name1, string name2) => name1?.CompareTo(name2) ?? 1; // Default comparer for Part type. // A null value means that this object is greater. public int CompareTo(Part comparePart) => comparePart == null ? 1 : PartId.CompareTo(comparePart.PartId); public override int GetHashCode() => PartId; public bool Equals(Part other) => other is null ? false : PartId.Equals(other.PartId); // Should also override == and != operators. } public class Example { public static void Main() { // Create a list of parts. var parts = new List<Part> { // Add parts to the list. new Part { PartName = "regular seat", PartId = 1434 }, new Part { PartName = "crank arm", PartId = 1234 }, new Part { PartName = "shift lever", PartId = 1634 }, // Name intentionally left null. new Part { PartId = 1334 }, new Part { PartName = "banana seat", PartId = 1444 }, new Part { PartName = "cassette", PartId = 1534 } }; // Write out the parts in the list. This will call the overridden // ToString method in the Part class. Console.WriteLine("\nBefore sort:"); parts.ForEach(Console.WriteLine); // Call Sort on the list. This will use the // default comparer, which is the Compare method // implemented on Part. parts.Sort(); Console.WriteLine("\nAfter sort by part number:"); parts.ForEach(Console.WriteLine); // This shows calling the Sort(Comparison<T> comparison) overload using // a lambda expression as the Comparison<T> delegate. // This method treats null as the lesser of two values. parts.Sort((Part x, Part y) => x.PartName == null && y.PartName == null ? 0 : x.PartName == null ? -1 : y.PartName == null ? 1 : x.PartName.CompareTo(y.PartName)); Console.WriteLine("\nAfter sort by name:"); parts.ForEach(Console.WriteLine); /* Before sort: ID: 1434 Name: regular seat ID: 1234 Name: crank arm ID: 1634 Name: shift lever ID: 1334 Name: ID: 1444 Name: banana seat ID: 1534 Name: cassette After sort by part number: ID: 1234 Name: crank arm ID: 1334 Name: ID: 1434 Name: regular seat ID: 1444 Name: banana seat ID: 1534 Name: cassette ID: 1634 Name: shift lever After sort by name: ID: 1334 Name: ID: 1444 Name: banana seat ID: 1534 Name: cassette ID: 1234 Name: crank arm ID: 1434 Name: regular seat ID: 1634 Name: shift lever */ } }
using System; using System.Collections.Generic; class Program { static Dictionary<Box, String> boxes; static void Main() { BoxSameDimensions boxDim = new BoxSameDimensions(); boxes = new Dictionary<Box, string>(boxDim); Console.WriteLine("Boxes equality by dimensions:"); Box redBox = new Box(8, 4, 8); Box greenBox = new Box(8, 6, 8); Box blueBox = new Box(8, 4, 8); Box yellowBox = new Box(8, 8, 8); AddBox(redBox, "red"); AddBox(greenBox, "green"); AddBox(blueBox, "blue"); AddBox(yellowBox, "yellow"); Console.WriteLine(); Console.WriteLine("Boxes equality by volume:"); BoxSameVolume boxVolume = new BoxSameVolume(); boxes = new Dictionary<Box, string>(boxVolume); Box pinkBox = new Box(8, 4, 8); Box orangeBox = new Box(8, 6, 8); Box purpleBox = new Box(4, 8, 8); Box brownBox = new Box(8, 8, 4); AddBox(pinkBox, "pink"); AddBox(orangeBox, "orange"); AddBox(purpleBox, "purple"); AddBox(brownBox, "brown"); } public static void AddBox(Box bx, string name) { try { boxes.Add(bx, name); Console.WriteLine("Added {0}, Count = {1}, HashCode = {2}", name, boxes.Count.ToString(), bx.GetHashCode()); } catch (ArgumentException) { Console.WriteLine("A box equal to {0} is already in the collection.", name); } } } public class Box { public Box(int h, int l, int w) { this.Height = h; this.Length = l; this.Width = w; } public int Height { get; set; } public int Length { get; set; } public int Width { get; set; } } class BoxSameDimensions : EqualityComparer<Box> { public override bool Equals(Box b1, Box b2) { if (b1 == null && b2 == null) return true; else if (b1 == null || b2 == null) return false; return (b1.Height == b2.Height && b1.Length == b2.Length && b1.Width == b2.Width); } public override int GetHashCode(Box bx) { int hCode = bx.Height ^ bx.Length ^ bx.Width; return hCode.GetHashCode(); } } class BoxSameVolume : EqualityComparer<Box> { public override bool Equals(Box b1, Box b2) { if (b1 == null && b2 == null) return true; else if (b1 == null || b2 == null) return false; return (b1.Height * b1.Width * b1.Length == b2.Height * b2.Width * b2.Length); } public override int GetHashCode(Box bx) { int hCode = bx.Height * bx.Length * bx.Width; return hCode.GetHashCode(); } } /* This example produces an output similar to the following: * Boxes equality by dimensions: Added red, Count = 1, HashCode = 46104728 Added green, Count = 2, HashCode = 12289376 A box equal to blue is already in the collection. Added yellow, Count = 3, HashCode = 43495525 Boxes equality by volume: Added pink, Count = 1, HashCode = 55915408 Added orange, Count = 2, HashCode = 33476626 A box equal to purple is already in the collection. A box equal to brown is already in the collection. * */
using System; using System.Collections; using System.Collections.Generic; class Program { static void Main(string[] args) { List<Box> Boxes = new List<Box>(); Boxes.Add(new Box(4, 20, 14)); Boxes.Add(new Box(12, 12, 12)); Boxes.Add(new Box(8, 20, 10)); Boxes.Add(new Box(6, 10, 2)); Boxes.Add(new Box(2, 8, 4)); Boxes.Add(new Box(2, 6, 8)); Boxes.Add(new Box(4, 12, 20)); Boxes.Add(new Box(18, 10, 4)); Boxes.Add(new Box(24, 4, 18)); Boxes.Add(new Box(10, 4, 16)); Boxes.Add(new Box(10, 2, 10)); Boxes.Add(new Box(6, 18, 2)); Boxes.Add(new Box(8, 12, 4)); Boxes.Add(new Box(12, 10, 8)); Boxes.Add(new Box(14, 6, 6)); Boxes.Add(new Box(16, 6, 16)); Boxes.Add(new Box(2, 8, 12)); Boxes.Add(new Box(4, 24, 8)); Boxes.Add(new Box(8, 6, 20)); Boxes.Add(new Box(18, 18, 12)); // Sort by an Comparer<T> implementation that sorts // first by the length. Boxes.Sort(new BoxLengthFirst()); Console.WriteLine("H - L - W"); Console.WriteLine("=========="); foreach (Box bx in Boxes) { Console.WriteLine("{0}\t{1}\t{2}", bx.Height.ToString(), bx.Length.ToString(), bx.Width.ToString()); } Console.WriteLine(); Console.WriteLine("H - L - W"); Console.WriteLine("=========="); // Get the default comparer that // sorts first by the height. Comparer<Box> defComp = Comparer<Box>.Default; // Calling Boxes.Sort() with no parameter // is the same as calling Boxs.Sort(defComp) // because they are both using the default comparer. Boxes.Sort(); foreach (Box bx in Boxes) { Console.WriteLine("{0}\t{1}\t{2}", bx.Height.ToString(), bx.Length.ToString(), bx.Width.ToString()); } // This explicit interface implementation // compares first by the length. // Returns -1 because the length of BoxA // is less than the length of BoxB. BoxLengthFirst LengthFirst = new BoxLengthFirst(); Comparer<Box> bc = (Comparer<Box>) LengthFirst; Box BoxA = new Box(2, 6, 8); Box BoxB = new Box(10, 12, 14); int x = LengthFirst.Compare(BoxA, BoxB); Console.WriteLine(); Console.WriteLine(x.ToString()); } } public class BoxLengthFirst : Comparer<Box> { // Compares by Length, Height, and Width. public override int Compare(Box x, Box y) { if (x.Length.CompareTo(y.Length) != 0) { return x.Length.CompareTo(y.Length); } else if (x.Height.CompareTo(y.Height) != 0) { return x.Height.CompareTo(y.Height); } else if (x.Width.CompareTo(y.Width) != 0) { return x.Width.CompareTo(y.Width); } else { return 0; } } } // This class is not demonstrated in the Main method // and is provided only to show how to implement // the interface. It is recommended to derive // from Comparer<T> instead of implementing IComparer<T>. public class BoxComp : IComparer<Box> { // Compares by Height, Length, and Width. public int Compare(Box x, Box y) { if (x.Height.CompareTo(y.Height) != 0) { return x.Height.CompareTo(y.Height); } else if (x.Length.CompareTo(y.Length) != 0) { return x.Length.CompareTo(y.Length); } else if (x.Width.CompareTo(y.Width) != 0) { return x.Width.CompareTo(y.Width); } else { return 0; } } } public class Box : IComparable<Box> { public Box(int h, int l, int w) { this.Height = h; this.Length = l; this.Width = w; } public int Height { get; private set; } public int Length { get; private set; } public int Width { get; private set; } public int CompareTo(Box other) { // Compares Height, Length, and Width. if (this.Height.CompareTo(other.Height) != 0) { return this.Height.CompareTo(other.Height); } else if (this.Length.CompareTo(other.Length) != 0) { return this.Length.CompareTo(other.Length); } else if (this.Width.CompareTo(other.Width) != 0) { return this.Width.CompareTo(other.Width); } else { return 0; } } }
Concurrency (동시성) (0) | 2023.08.16 |
---|---|
Marshaling: 복사 및 고정 (0) | 2021.10.15 |
Array Marshaling (0) | 2021.10.15 |
Debugging Tips (0) | 2021.09.15 |
Equals, IEquatable<T> (0) | 2021.08.15 |
사용자 객체 디버거 표시 속성
[StructLayout(LayoutKind.Sequential, Pack = 1)] [DebuggerDisplay("k4a_quaternion_st: wxyz({w}, {x}, {y}, {z})")] public readonly struct k4a_quaternion_st { public readonly float w; public readonly float x; public readonly float y; public readonly float z; public k4a_quaternion_st(float w, float x, float y, float z) { this.w = w; this.x = x; this.y = y; this.z = z; } public static implicit operator Quaternion(k4a_quaternion_st q) { return new Quaternion(q.x, q.y, q.z, q.w); } public static implicit operator k4a_quaternion_st(Quaternion q) { return new k4a_quaternion_st(q.W, q.X, q.Y, q.Z); } }
Concurrency (동시성) (0) | 2023.08.16 |
---|---|
Marshaling: 복사 및 고정 (0) | 2021.10.15 |
Array Marshaling (0) | 2021.10.15 |
Comparisons and Sorts (0) | 2021.10.15 |
Equals, IEquatable<T> (0) | 2021.08.15 |
public static bool ReferenceEquals(object left, object right); public static bool Equals(object left, object right); // 재정의하는 경우 IEquatable<T>를 구현해야 한다. // (값에 고유의 의미 체계를 부여하기 위해 IStructuralEquality를 구현하기도 함) public virtual bool Equals(object right); // 주로 성능을 개선하기 위해 재정의 public static bool operator == (MyClass left, MyClass right);
public static bool Equals(object left, object right) { if (object.ReferenceEquals(left, right)) return true; if (object.ReferenceEquals(left, null) || object.ReferenceEquals(right, null)) return false; return left.Equals(right); }
동일성의 수학적 속성
public class MyClass : IEquatable<MyClass> { public override bool Equals(object other) { // C# 메서드 내에서 this는 절대 null이 될 수 없다. if (object.ReferenceEquals(right, null)) return false; if (object.ReferenceEquals(this, other)) return true; if (this.GetType() != other.GetType()) return false; return this.Equals(other as MyCalss) } // IEquatable<MyClass> public bool Equals(MyClass other) { ; } }
Concurrency (동시성) (0) | 2023.08.16 |
---|---|
Marshaling: 복사 및 고정 (0) | 2021.10.15 |
Array Marshaling (0) | 2021.10.15 |
Comparisons and Sorts (0) | 2021.10.15 |
Debugging Tips (0) | 2021.09.15 |