यदि structs सरल प्रकार से बने होते हैं तो आप पॉइंटर्स की एक सरणी बना सकते हैं। सी # में हाँ पॉइंटर्स आपके जैसे मामलों के लिए बहुत उपयोगी हैं। यद्यपि सीमाएं हैं। मूल संरचनाओं को Array
में संग्रहीत किया जाना चाहिए और List<>
नहीं। unsafe
निर्माण ध्वज के साथ संकलित नीचे दिए गए उदाहरण को देखें।
[StructLayout(LayoutKind.Sequential)]
public struct Vec3
{
public double X, Y, Z;
public double Mag { get { return Math.Sqrt(X * X + Y * Y + Z * Z); } }
}
public unsafe class Vec3ArrayProxy
{
Vec3*[] ptr = null; //internal array of pointers
public Vec3ArrayProxy(Vec3[] array)
{
ptr = new Vec3*[array.Length]; //allocate array
fixed (Vec3* src = array) //src holds pointer from source array
{
for (int i = 0; i < array.Length; i++)
{
ptr[i] = &src[i]; //take address of i-th element
}
}
}
public Vec3ArrayProxy(Vec3ArrayProxy other)
{
//just use all the existing pointers
ptr = (Vec3*[])other.ptr.Clone();
//or I could say:
//ptr = other.ptr;
}
// Access values with index
public Vec3 this[int index]
{
get { return *ptr[index]; }
set { *ptr[index] = value; }
}
public int Count { get { return ptr.Length; } }
// Access the array of pointers
public Vec3*[] PtrArray { get { return ptr; } }
// Copy the values of original array into new array
public Vec3[] ToArrayCopy()
{
Vec3[] res = new Vec3[ptr.Length];
for (int i = 0; i < res.Length; i++)
{
res[i] = *ptr[i];
}
return res;
}
}
unsafe class Program
{
static void Main(string[] args)
{
const int N = 10; //size of array
// Allocate array in memory
Vec3[] array = new Vec3[N];
// Assign values into array
for (int i = 0; i < N; i++)
{
array[i] = new Vec3() { X = i, Y = 0, Z = 0 };
}
//Build proxy to array (with pointers)
Vec3Array A = new Vec3Array(array);
// Reference the same pointers as A
Vec3Array B = new Vec3Array(A);
// Change the original array
array[4].X = -4;
// Or change via a copy
A.PtrArray[5]->Y = -5;
// Or assign a new value
B[0] = B[9];
// Show contents of array via proxy A
Console.WriteLine("{0,-6}|{1,6}|{2,6}|{3,6}|{4,6}",
"i", "X", "Y", "Z", "Mag");
for (int i = 0; i < N; i++)
{
Console.WriteLine("{0,6}|{1,6:F2}|{2,6:F2}|{3,6:F2}|{4,6:F3}",
i + 1, A[i].X, A[i].Y, A[i].Z, A[i].Mag);
}
}
}
लंबे कोड के लिए खेद है, लेकिन मैं संरचना पॉइंटर्स की सभी सुविधाओं को दिखाना चाहता था।कारण List<>
काम नहीं करेगा क्योंकि आप किसी सूची तत्व में पॉइंटर नहीं ले सकते हैं। क्या तुम सच में वास्तव में वास्तव में एक List<>
का उपयोग करना चाहिए, तो निम्न कोड के साथ निजी क्षेत्र _items
से सरणी निकालें:
static T[] ExtractArray(List<T> list)
{
//list.TrimExcess();
var t = list.GetType();
var items = t.GetField("_items",
BindingFlags.NonPublic | BindingFlags.Instance);
return items.GetValue(list) as T[];
}
क्रूड यह हो सकता है, यह काम करता है और एक बार आप एक बार List<>
पर प्रतिबिंब बना दिया है, आप परिणाम को स्थिर क्षेत्र में कैश कर सकते हैं और प्रत्येक बार केवल items.GetValue(list)
पर कॉल कर सकते हैं।
एक वर्ग है कि संरचना संग्रहीत करता है बनाएँ। समयपूर्व अनुकूलन के साथ बहुत सावधान रहें, पॉइंटर्स के सरणी में लुसी कैश इलाके है। –
संरचना से संदर्भ कितना बड़ा है? संरचनाओं को छोटा माना जाना चाहिए; यदि वे किसी संदर्भ से इतने बड़े हैं कि प्रतिलिपि समय आपकी बाधा है तो हो सकता है कि आप पहले स्थान पर किसी संरचना का उपयोग नहीं करना चाहें। क्या आप अधिक जानकारी दे सकते हैं? –
खैर, संदर्भ केवल 4bytes लगता है, इसलिए कुछ भी एक नाव या पूर्णांक से भी बड़ा पहले से ही उस से भी बड़ा है। यदि आप गणित करते हैं, भले ही मैं बहुत मामूली हूं और केवल एक साधारण वेक्टर 4 स्टोर करता हूं, अनुपात पहले से ही 4: 1 है, और यह एक बड़ी संरचना के करीब कुछ भी नहीं है। प्रोफाइलिंग प्रोफाइल के बारे में पूछने के लिए – Adi