असल में, मैं इसे विफल नहीं कर सकता - कम से कम, स्मृति में उत्पन्न करते समय।
चलो बस public readonly
फ़ील्ड के साथ शुरू करें (इसलिए हम किसी भी एक्सेसबिलिटी नियमों को तोड़ नहीं रहे हैं); मेरा पहला प्रयास के रूप में नीचे है, और यह ठीक काम करता है:
private readonly int i;
कोड तो ऊपर ओह-तो-अस्पष्ट देता है: यदि क्षेत्र private
है
using System;
using System.Reflection;
using System.Reflection.Emit;
class Foo
{
public readonly int i;
public int I { get { return i; } }
public Foo(int i) { this.i = i; }
}
static class Program
{
static void Main()
{
var setter = CreateWriteAnyInt32Field(typeof(Foo), "i");
var foo = new Foo(123);
setter(foo, 42);
Console.WriteLine(foo.I); // 42;
}
static Action<object, int> CreateWriteAnyInt32Field(Type type, string fieldName)
{
var field = type.GetField(fieldName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var method = new DynamicMethod("evil", null,
new[] { typeof(object), typeof(int) });
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, type);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, field);
il.Emit(OpCodes.Ret);
return (Action<object, int>)method.CreateDelegate(typeof(Action<object, int>));
}
}
केवल समय यह दिलचस्प हो जाता है है :
ऑपरेशन रनटाइम को अस्थिर कर सकता है।
var method = new DynamicMethod("evil", null,
new[] { typeof(object), typeof(int) }, field.DeclaringType);
कुछ अन्य आंतरिक चेकों किया जा सकता है skipVisibility
को सक्षम करने से:
लेकिन हम नाटक है कि विधि क्षेत्र के घोषित प्रकार के अंदर है द्वारा कि चारों ओर पाने के
var method = new DynamicMethod("evil", null,
new[] { typeof(object), typeof(int) }, field.DeclaringType, true);
हालांकि, ध्यान दें कि स्टैंडअलोन असेंबली उत्पन्न करते समय यह सब संभव नहीं है। वास्तविक डीएलएस बनाते समय आपको बहुत अधिक मानकों पर रखा जाता है। इस कारण से, precompiler
उपकरण (असेंबली प्री-जेनरेट करने के लिए) इन-मेमोरी मेटा-प्रोग्रामिंग कोड के परिदृश्यों की एक ही श्रृंखला को संभाल नहीं सकता है।
मैं इसे तुरंत देखूंगा। हो सकता है कि मेरी समस्या सख्ती से पढ़ाई वाले क्षेत्रों से संबंधित न हो। मजाकिया बात यह है कि मेरा कोड मोनो पर काम करता है और .NET पर नहीं है। –
दोह। मैं DeclaringType प्रदान करने में विफल रहा। लेकिन अब मुझे आश्चर्य है - यह क्यों काम करता है? क्या एक पाठक क्षेत्र केवल वस्तु के निर्माता से लिखने योग्य नहीं होना चाहिए? एक जवाब के लिए धन्यवाद, वैसे भी। –
@PiotrZierhoffer कई चीजें केवल कंपाइलर पर लागू होती हैं, और पूरी तरह से 'PEVerify' में। आखिरकार, आप प्रतिबिंब के माध्यम से 'रीडोनली' फ़ील्ड बदल सकते हैं, और सीरियलाइजर्स/कटाइज़र अक्सर ** पूरी तरह से ** कन्स्ट्रक्टर को छोड़ सकते हैं, इसलिए अगर ऐसा होता तो –