কিভাবে স্পষ্টভাবে একটি আউট আর্গুমেন্ট বাতিল?


103

আমি একটি কল করছি:

myResult = MakeMyCall(inputParams, out messages);

তবে আমি আসলে বার্তাগুলি সম্পর্কে চিন্তা করি না। যদি এটি একটি ইনপুট প্যারামিটার হত তবে আমি কেবল কোনও শূন্যপদে পাস করব সে সম্পর্কে চিন্তা করছিলাম না। এটি যদি ফিরে আসে তবে আমি কিছু চিন্তা করিনি আমি কেবল এটি ছেড়ে দেব।

আউট আউট এর সাথে অনুরূপ কিছু করার কোনও উপায় আছে, বা আমার কী এমন কোনও ভেরিয়েবল ঘোষণা করার দরকার যা আমি এড়িয়ে যাব?


এখানে অনুরূপ প্রশ্ন: স্ট্যাকওভারফ্লো.com
ডানক


ধন্যবাদ! লজ্জাজনক এটি সর্বশেষ সংস্করণে নেই।
অ্যান্ড্রু ডাকার

উত্তর:


103

সি # 7.0 দিয়ে শুরু করে, পরামিতিগুলির পূর্বাভাস দেওয়ার পাশাপাশি সেগুলি উপেক্ষা করা এড়ানো সম্ভব।

public void PrintCoordinates(Point p)
{
    p.GetCoordinates(out int x, out int y);
    WriteLine($"({x}, {y})");
}

public void PrintXCoordinate(Point p)
{
    p.GetCoordinates(out int x, out _); // I only care about x
    WriteLine($"{x}");
}

সূত্র: https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/


4
দুর্ভাগ্যক্রমে, এটি সি # 7 (এপ্রিল 2017 হিসাবে) এর অন্তর্ভুক্ত নয়।
টিআই

4
@tia। আমি আমার উত্তর আপডেট করেছি। স্পষ্টতই, ওয়াইল্ডকার্ডের চরিত্রটি বদলে নেওয়া *হয়েছিল _। দুঃখিত এটি এত দীর্ঘ সময় নিয়েছে।
নোলোনার

14
out voidসিনট্যাক্সের জন্য তাদের ধারণাগুলি আটকে থাকা উচিত এবং আন্ডারস্কোরটি একটি বিজোড় পছন্দ বলে মনে হয়।
ডেভিড অ্যান্ডারসন

4
@ ডেভিডএন্ডারসন-ডিসিওএম যদিও আমি আন্ডারস্কোরের কোন অনুরাগী নই, আমি মনে করি ওভারলোড রেজোলিউশনের জন্য তাদের টাইপ নামটি প্রয়োজন।
জোনাথন অ্যালেন

দেখে মনে হচ্ছে এটি এখনও একটি প্যারামিটার তৈরি করে, কারণ আমি _ = {a value};কোনও সংকলন ত্রুটি না করে ফাংশন কল করার পরে লাইনটি যুক্ত করতে পারি ।
Bip901

37

দুর্ভাগ্যক্রমে আপনার কিছু পাস করার প্রয়োজন কারণ এটি সেট করার জন্য পদ্ধতিটি প্রয়োজন। সুতরাং আপনি প্রেরণ করতে পারবেন না nullকারণ পদ্ধতিটি এটি সেট করার জন্য প্রয়োজনীয় হয়ে উঠছিল।

কদর্যতা আড়াল করার জন্য একটি পদ্ধতি হ'ল পদ্ধতিটি অন্য পদ্ধতিতে মোড়ানো হবে যা outআপনার জন্য প্যারামিটারটি পছন্দ করে:

String Other_MakeMyCall(String inputParams)
{
    String messages;

    return MakeMyCall(inputParams, out messages);
}

তারপরে আপনার প্রয়োজনীয় প্যারামিটারগুলির Other_MakeMyCallসাথে ঝাঁকুনি ছাড়াই আপনি কল করতে পারেন out


37

আপনাকে এমন একটি ভেরিয়েবল ঘোষণা করতে হবে যা আপনি এড়িয়ে যাবেন। এটি ট্রান্সপার্স (বা ট্রাইউইউথ ওয়েলস) প্যাটার্নের ক্ষেত্রে সাধারণত দেখা যায় যখন ব্যবহারকারীর ইনপুটটির বৈধতা পরীক্ষা করার জন্য ব্যবহার করা হয় (উদাহরণস্বরূপ এটি সংখ্যার হিসাবে পার্স করা যায়?) প্রকৃত বিশদ মান সম্পর্কে চিন্তা না করেই।

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


একটি বাস্তববাদী অ্যান্টি-প্যাটার্নের আরও
জোডরেল

11

যদি মূল ফাংশনটি এভাবে ঘোষিত হয়:

class C
{
    public Result MakeMyCall(Object arg, out List<String> messages);
}

আপনি এর মতো কোনও এক্সটেনশন পদ্ধতি ঘোষণা করতে পারেন:

static class CExtension
{
    public static Result MakeMyCall(this C obj, Object arg)
    {
        List<String> unused;
        return obj.MakeMyCall(arg, out unused);
    }
}

এক্সটেনশন পদ্ধতিটি ওভারলোডের মতো আচরণ করবে যা আউট প্যারামিটারটিকে alচ্ছিক করে তোলে।


4

ভিজ্যুয়াল বেসিক সংকলক এটি একটি ডামি ভেরিয়েবল তৈরি করে করে। সি # এটি করতে পারে, আপনি যদি মাইক্রোসফ্টকে এটির একটি ভাল ধারণা বোঝাতে পারেন।


0

যদি messagesপ্রয়োগগুলির ক্লাস হয় তবে আপনার এড়ানো IDisposableউচিত নয়। নিম্নলিখিত পদ্ধতির মতো কিছু বিবেচনা করুন (কিছুক্ষণের মধ্যে আমি সি # লিখেনি বলে কৃত্রিমভাবে সঠিক হতে পারে না):

using (FooClass messages) {
    myResult = MakeMyCall(inputParams, messages);
}

একবার usingব্লকের বাইরে গেলে messagesস্বয়ংক্রিয়ভাবে নিষ্পত্তি হবে।


4
মজাদার. কিন্তু আপনি কি ব্যবহারের বিবৃতিতে পরিবর্তনশীল আরম্ভ করতে হবে না?
অরেগনহোস্ট

4
@ অরেগনগোস্ট: হ্যাঁ, আপনি করেন। এবং যদি আপনি ব্যবহারের বিবৃতিতে ভেরিয়েবলের মান পরিবর্তন করেন তবে এটি এখনও মূল মান যা নিষ্পত্তি হয়।
জন স্কিটি

পছন্দ করেছেন এখনও এটি এখনও মূল্যবান হয় যা নিষ্পত্তি হয়।
ওরখান আলিখানোভ

@ ওরখানআলিখানভ: সংকলকটি মূলত এর শুরুতে পরিবর্তকের একটি অনুলিপি গ্রহণ করে using বিবৃতি । সুতরাং ব্লকের মধ্যে যে ভেরিয়েবলের মান পরিবর্তন করা যায় তা পরিবর্তিত হয় না যা কোন বস্তুর নিষ্পত্তি হয়।
জন স্কিটি

যাইহোক, সেখানে থাকা উচিত out messages
ওর্খন আলিখনভ

0

আউট প্যারামিটারের জন্য আপনাকে অবশ্যই একটি ভেরিয়েবল পাস করতে হবে। ভেরিয়েবলটি পাস করার আগে আপনাকে আরম্ভ করতে হবে না:

MyMessagesType messages;
myResult = MakeMyCall(inputParams, out messages); 

সাধারণত, আপনি কল করার পরে 'বার্তাগুলি' উপেক্ষা করতে পারেন - যদি না 'বার্তাগুলি' কোনও কারণে নিষ্পত্তি করার প্রয়োজন হয় যেমন সীমাবদ্ধ সিস্টেম রিসোর্সের ব্যবহার, এই ক্ষেত্রে আপনাকে ডিসপোজ () কল করা উচিত:

messages.Dispose();

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

messages = null; // Allow GC to reclaim memory for reference type.

messages = new MyMessageType(); // Allow GC to reclaim memory for value type.

0

এই ক্ষেত্রে আমি সমকালীন অভিধানের জন্য একটি জেনেরিক এক্সটেনশন পদ্ধতি তৈরি করেছি যার কোনও মুছুন বা সরান পদ্ধতি নেই।

//Remove item from list and ignore reference to removed item
public static void TryRemoveIgnore<K,T>(this ConcurrentDictionary<K,T> dictionary, K key)
{
    T CompletelyIgnored;
    dictionary.TryRemove(key, out CompletelyIgnored);
}

সমকালীন অভিধানের উদাহরণ থেকে যখন ফোন করা হয়:

ClientList.TryRemoveIgnore(client.ClientId);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.