c# - আমি প্রতিফলন ব্যবহার করে#C তে একটি ব্যক্তিগত পাঠযোগ্য ক্ষেত্র পরিবর্তন করতে পারি?




reflection field (6)

আমি ভাবছি, প্রতিফলন ব্যবহার করে অনেক কিছু করা যেতে পারে, কন্সট্রাকটরটি তার মৃত্যুদণ্ড কার্যকর করার পরে কি আমি ব্যক্তিগত পাঠযোগ্য ক্ষেত্র পরিবর্তন করতে পারি?
(নোট: শুধু কৌতূহল)

public class Foo
{
 private readonly int bar;

 public Foo(int num)
 {
  bar = num;
 }

 public int GetBar()
 {
  return bar;
 }
}

Foo foo = new Foo(123);
Console.WriteLine(foo.GetBar()); // display 123
// reflection code here...
Console.WriteLine(foo.GetBar()); // display 456

অনিরাপদ ব্যবহার করে এটি করার আরেকটি সহজ উপায় (অথবা আপনি DLLImport এর মাধ্যমে একটি সি পদ্ধতিতে ক্ষেত্রটি পাস করতে এবং এটি সেট করতে পারেন)।

using System;

namespace TestReadOnly
{
    class Program
    {
        private readonly int i;

        public Program()
        {
            i = 66;
        }

        private unsafe void ForceSet()
        {
            fixed (int* ptr = &i) *ptr = 123;
        }

        static void Main(string[] args)
        {
            var program = new Program();
            Console.WriteLine("Contructed Value: " + program.i);
            program.ForceSet();
            Console.WriteLine("Forced Value: " + program.i);
        }
    }
}

আপনি করতে পারেন:

typeof(Foo)
   .GetField("bar",BindingFlags.Instance|BindingFlags.NonPublic)
   .SetValue(foo,567);

আমি অন্যান্য উত্তরগুলির সাথে একমত যে এতে সাধারণত কাজ করে এবং বিশেষ করে ই। লিপার্টের মন্তব্যের সাথে যে এটি নথিভুক্ত আচরণ নয় এবং তাই ভবিষ্যত-প্রমাণ কোড নয়।

তবে, আমরা আরেকটি বিষয় লক্ষ্য করেছি। যদি আপনি বিধিবদ্ধ অনুমতিগুলির সাথে পরিবেশে আপনার কোডটি চালাচ্ছেন তবে আপনার ব্যতিক্রম হতে পারে।

আমাদের একটি কোড আছে যেখানে আমাদের কোডগুলি আমাদের মেশিনে সূক্ষ্ম কাজ করেছে, কিন্তু কোডটি যখন একটি সীমিত পরিবেশে দৌড়ে গিয়েছিল তখন আমরা একটি VerificationException পেয়েছি। অপরাধী একটি পঠনযোগ্য ক্ষেত্রের setter প্রতি প্রতিফলন কল ছিল। আমরা যে ক্ষেত্রের readonly সীমাবদ্ধতা মুছে ফেলা যখন এটি কাজ।


আমি শুধু যুক্ত করতে চাই যে যদি আপনি ইউনিট পরীক্ষার জন্য এই জিনিসটি করতে চান তবে আপনি এটি ব্যবহার করতে পারেন:

A) PrivateObject ক্লাস

বি) আপনি এখনও একটি PrivateObject উদাহরণ প্রয়োজন হবে, কিন্তু আপনি ভিজ্যুয়াল স্টুডিও সঙ্গে "অ্যাক্সেসর" বস্তু উত্পন্ন করতে পারেন। কিভাবে: ব্যক্তিগত অ্যাক্সেসার পুনর্জন্ম

যদি আপনি আপনার কোডের ইউনিট টেস্টিংয়ের বাইরে কোনও বস্তুর ব্যক্তিগত ক্ষেত্রগুলি সেট করে থাকেন তবে এটি "কোড গন্ধ" এর একটি উদাহরণ হবে বলে মনে হয়, সম্ভবত আপনি অন্য তৃতীয় কারণে এটি করতে চাইলে আপনি এটি করতে চান। লাইব্রেরি এবং আপনি লক্ষ্য ক্লাস কোড পরিবর্তন করতে পারবেন না। তবুও আপনি সম্ভবত তৃতীয় পক্ষের সাথে যোগাযোগ করতে চান, আপনার পরিস্থিতি ব্যাখ্যা করুন এবং দেখুন যে তারা এগিয়ে যাবে না এবং আপনার প্রয়োজনীয়তা অনুসারে তাদের কোড পরিবর্তন করবে।


এটা করো না।

আমি মাত্র একটি দিন অতিবাহিত বাগ সমাধান যেখানে বস্তু তাদের নিজস্ব ঘোষিত ধরনের হতে পারে না।

পঠনযোগ্য ক্ষেত্র পরিবর্তন একবার কাজ। কিন্তু আপনি যদি আবার এটি সংশোধন করার চেষ্টা করেন, তবে আপনি এইরকম পরিস্থিতিতে পেতে পারেন:

SoundDef mySound = Reflection_Modified_Readonly_SoundDef_Field;
if( !(mySound is SoundDef) )
    Log("Welcome to impossible-land!"); //This would run

তাই এটা করবেন না।

এটি ছিল মোনো রানটাইম (ইউনিটি গেম ইঞ্জিন)।


সুস্পষ্ট জিনিস এটি চেষ্টা করা হয়:

using System;
using System.Reflection;

public class Test
{
    private readonly string foo = "Foo";

    public static void Main()
    {
        Test test = new Test();
        FieldInfo field = typeof(Test).GetField
            ("foo", BindingFlags.Instance | BindingFlags.NonPublic);
        field.SetValue(test, "Hello");
        Console.WriteLine(test.foo);
    }        
}

এই জরিমানা কাজ করে। (জাভাতে বিভিন্ন নিয়ম রয়েছে, আকর্ষণীয়ভাবে - আপনাকে Field অ্যাক্সেসযোগ্যভাবে স্পষ্টভাবে সেট করতে হবে এবং এটি কেবলমাত্র উদাহরণ ক্ষেত্রের জন্যই কাজ করবে।)






readonly