আমি কীভাবে আমার ক্লাসের জন্য কাস্টম কাস্ট সমর্থন সরবরাহ করব?


102

আমি আমার ক্লাসকে অন্য ধরণের কাস্টিংয়ের জন্য কীভাবে সহায়তা সরবরাহ করব? উদাহরণস্বরূপ, যদি আমার নিজের ব্যবস্থাপনার নিজস্ব প্রয়োগ থাকে byte[]এবং আমি লোকদের আমার ক্লাসটি এমন একটিতে দিতে দিতে চাই byte[], যা কেবলমাত্র ব্যক্তিগত সদস্যকে ফিরিয়ে দেবে, আমি কীভাবে এটি করব?

এগুলিকেও একটি স্ট্রিংয়ে ফেলে দেওয়া কি সাধারণ অভ্যাস, নাকি আমার ToString()(বা উভয়) ওভাররাইড করা উচিত ?

উত্তর:


112

আপনি রূপান্তর অপারেটর ওভাররাইড করতে হবে যেকোন একটি ব্যবহার করে implicitবা explicitআপনি ব্যবহারকারীদের এটি কাস্ট করার জন্য অথবা আপনি এটি স্বয়ংক্রিয়ভাবেই আপনার ঘটতে করতে চান কিনা করতে চান কিনা উপর নির্ভর করে। সাধারণত, একটি দিক সর্বদা কার্যকর হয়, আপনি যেখানে ব্যবহার implicitকরেন সেদিকেই অন্য দিকটি কখনও কখনও ব্যর্থ হতে পারে, আপনি যেখানে ব্যবহার করেন সেখানেই explicit

বাক্য গঠনটি এরকম:

public static implicit operator dbInt64(Byte x)
{
    return new dbInt64(x);
}

অথবা

public static explicit operator Int64(dbInt64 x)
{
    if (!x.defined)
        throw new DataValueNullException();
    return x.iVal;
}

উদাহরণস্বরূপ, আপনার কাস্টম প্রকার থেকে বলুন ( MyType-> byte[]সর্বদা কার্যকর হবে):

public static implicit operator byte[] (MyType x)
{
    byte[] ba = // put code here to convert x into a byte[]
    return ba;
}

অথবা

public static explicit operator MyType(byte[] x)
{
    if (!CanConvert)
        throw new DataValueNullException();

    // Factory to convert byte[] x into MyType
    MyType mt = MyType.Factory(x);
    return mt;
}

36

আপনি কোনও শব্দ explicitবা implicitকীওয়ার্ড ব্যবহার করে আপনার শ্রেণিতে রূপান্তর অপারেটরগুলি ঘোষণা করতে পারেন ।

থাম্বের সাধারণ নিয়ম হিসাবে, implicitরূপান্তর অপারেটরগুলি কেবল তখনই সরবরাহ করতে হবে যখন রূপান্তর সম্ভবত ব্যর্থ হয় না। explicitরূপান্তর ব্যর্থ হতে পারে যখন রূপান্তর অপারেটর ব্যবহার করুন ।

public class MyClass
{
    private byte[] _bytes;

    // change explicit to implicit depending on what you need
    public static explicit operator MyClass(byte[] b)
    {
        MyClass m = new MyClass();
        m._bytes = b;
        return m;
    }

    // change explicit to implicit depending on what you need
    public static explicit operator byte[](MyClass m)
    {
        return m._bytes;
    }
}

ব্যবহার explicitমানে হল আপনার ক্লাসের ব্যবহারকারীদের একটি সুনির্দিষ্ট রূপান্তর করতে প্রয়োজন হবে:

byte[] foo = new byte[] { 1, 2, 3, 4, 5 };
// explicitly convert foo into an instance of MyClass...
MyClass bar = (MyClass)foo;
// explicitly convert bar into a new byte[] array...
byte[] baz = (byte[])bar;

ব্যবহার implicitমানে হল আপনার ক্লাসের ব্যবহারকারীদের একটি সুনির্দিষ্ট রূপান্তর সঞ্চালন প্রয়োজন হবে না, এটা সব স্বচ্ছভাবে ঘটবে:

byte[] foo = new byte[] { 1, 2, 3, 4, 5 };
// imlpicitly convert foo into an instance of MyClass...
MyClass bar = foo;
// implicitly convert bar into a new byte[] array...
byte[] baz = bar;

6

আমি এমন কিছু পদ্ধতি পছন্দ করতে চাই যা কাস্ট অপারেটরকে ওভারলোড করার চেয়ে তা করবে।

দেখুন স্পষ্ট এবং অন্তর্নিহিত C # কিন্তু মনে রাখবেন যে উদাহরণস্বরূপ থেকে স্পষ্ট পদ্ধতি ব্যবহার করে, আপনি যদি একটি করুন:

string name = "Test";
Role role = (Role) name;

তাহলে সবকিছু ঠিক আছে; তবে, আপনি যদি ব্যবহার করেন:

object name = "Test";
Role role = (Role) name;

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


আপনি যে উদাহরণটির সাথে লিঙ্ক করেছেন, তা দেখে মনে হচ্ছে প্রতিটি কাস্টে অবজেক্টের নতুন উদাহরণ তৈরি হয়েছে। ক্লাসের কোনও বর্তমান সদস্যের উপর কীভাবে সুনির্দিষ্ট ক্রিয়াকলাপ পাবেন / সেট করবেন তা সম্পর্কে কোনও ধারণা?
এসাক

3

কাস্টম কাস্ট সাপোর্টের জন্য আপনাকে কাস্ট অপারেটরগুলি সরবরাহ করতে হবে (স্পষ্ট বা অন্তর্নিহিত)। এনকোড স্ট্রিং ক্লাসের নীচের উদাহরণটি কাস্টম এনকোডিং সহ স্ট্রিংটির সরল বাস্তবায়ন (আপনি যদি বিশাল-বিশাল স্ট্রিংগুলি প্রসেস করতে এবং মেমরি গ্রাহনের সমস্যায় পড়তে পারেন তবে দরকারী হতে পারে কারণ নেট স্ট্রিংগুলি ইউনিকোড হয় - প্রতিটি অক্ষর মেমরির 2 বাইট নেয় - এবং এনকোড স্ট্রিং প্রতি চার্চে 1 বাইট নিতে পারে)।

এনকোডডস্ট্রিং বাইট [] এবং সিস্টেম.স্ট্রিংয়ে রূপান্তরিত হতে পারে। কোডের মন্তব্যে কিছুটা হালকা আলোড়িত হয় এবং অন্তর্নিহিত রূপান্তর বিপজ্জনক হতে পারে যখন একটি উদাহরণও ব্যাখ্যা করে।

সাধারণত কোনও রূপান্তর অপারেটরকে প্রথম স্থানে ঘোষণার জন্য আপনার খুব ভাল কারণ প্রয়োজন কারণ কারণ।

আরও পড়া এমএসডিএন- তে পাওয়া যায় ।

class Program
{
    class EncodedString
    {
        readonly byte[] _data;
        public readonly Encoding Encoding;

        public EncodedString(byte[] data, Encoding encoding)
        {
            _data = data;
            Encoding = encoding;
        }

        public static EncodedString FromString(string str, Encoding encoding)
        {
            return new EncodedString(encoding.GetBytes(str), encoding);
        }

        // Will make assumption about encoding - should be marked as explicit (in fact, I wouldn't recommend having this conversion at all!)
        public static explicit operator EncodedString(byte[] data)
        {
            return new EncodedString(data, Encoding.Default);
        }

        // Enough information for conversion - can make it implicit
        public static implicit operator byte[](EncodedString obj)
        {
            return obj._data;
        }

        // Strings in .Net are unicode so we make no assumptions here - implicit
        public static implicit operator EncodedString(string text)
        {
            var encoding = Encoding.Unicode;
            return new EncodedString(encoding.GetBytes(text), encoding);
        }

        // We have all the information for conversion here - implicit is OK
        public static implicit operator string(EncodedString obj)
        {
            return obj.Encoding.GetString(obj._data);
        }
    }

    static void Print(EncodedString format, params object[] args)
    {
        // Implicit conversion EncodedString --> string
        Console.WriteLine(format, args);
    }

    static void Main(string[] args)
    {
        // Text containing russian letters - needs care with Encoding!
        var text = "Привет, {0}!";

        // Implicit conversion string --> EncodedString
        Print(text, "world");

        // Create EncodedString from System.String but use UTF8 which takes 1 byte per char for simple English text
        var encodedStr = EncodedString.FromString(text, Encoding.UTF8);
        var fileName = Path.GetTempFileName();

        // Implicit conversion EncodedString --> byte[]
        File.WriteAllBytes(fileName, encodedStr);

        // Explicit conversion byte[] --> EncodedString
        // Prints *wrong* text because default encoding in conversion does not match actual encoding of the string
        // That's the reason I don't recommend to have this conversion!
        Print((EncodedString)File.ReadAllBytes(fileName), "StackOverflow.com");

        // Not a conversion at all. EncodingString is instantiated explicitly
        // Prints *correct* text because encoding is specified explicitly
        Print(new EncodedString(File.ReadAllBytes(fileName), Encoding.UTF8), "StackOverflow.com");

        Console.WriteLine("Press ENTER to finish");
        Console.ReadLine();
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.