সি # 4.0 outচ্ছিক আউট / রেফ আর্গুমেন্ট


212

সি # 4.0 কি optionচ্ছিক outবা তর্ককে অনুমতি দেয় ref?


2
ওয়েল, সি ++ কার্যকরভাবে তাদের "আউট" পরামিতিগুলির জন্য রয়েছে - আপনার কাছে একটি ঠিকানা যুক্তি নাল থেকে শুরু হতে পারে এবং লাইব্রেরি কোড লিখতে এটি সাধারণ বিষয় যা পয়েন্টারটি শূন্য না হলে কেবল এই জাতীয় রিটার্নের কাঠামো তৈরি করে। এটি একটি আইডিয়ম সিআইপিগুলিতে "alচ্ছিক যুক্তি" জন্য নাল ব্যবহার করতে ফিরে যাচ্ছে।
অ্যান্ডি ডেন্ট

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

5
জিনিসগুলি কীভাবে বাস্তবায়িত হয় বা anচ্ছিক প্যারামিটার আসলে কী তা বিবেচনা করে এটিকে বোঝায় না। তবে রোমকিন্স যেমন বলেছিলেন, "alচ্ছিক আর্গুমেন্টগুলি" পাওয়া খুব ভাল লাগবে - সিএলআরের চেয়ে ইংরেজিতে পার্স করা এবং এটি যুক্তিযুক্ত এবং আইএমওতে কাম্য হয়ে ওঠে।
অ্যাডাম টলি

9
সি # হয় না, তবে ভিবি.এনইটি করে।
জেসন

5
এটি মারধর করা হয়েছে, তবে, আমি সাহায্য করতে পারি না তবে alচ্ছিক আর্গুমেন্টের পক্ষে আমার সমর্থন উল্লেখ করতে পারি। আমি nullডিফল্ট সেট করার মাধ্যমে I চ্ছিক যুক্তিগুলিতে মোটামুটি অভ্যস্ত হয়ে পড়েছি ( আমি পিএইচপি থেকে এসেছি ) এবং nullযুক্তিটি জনসাধারণের সাথে এগিয়ে যাওয়ার জন্য পরীক্ষা করছি ( যারা পরিচিত, মনে করিpreg_match() ) যাইহোক, যদিও আমি প্রযুক্তিগত দিক থেকে বুঝতে পারি যে এটি বর্তমানে হতে পারে অসম্ভব, এবং পিএইচপি এবং সি # তুলনামূলক অতুলনীয়, এটি উপলব্ধ থাকা এখনও একটি " সুন্দর " সরঞ্জাম হবে would
ড্যান লগ

উত্তর:


93

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

কনস্ট্রাক্টর, পদ্ধতি, সূচক এবং প্রতিনিধি প্রকারের সাধারণ পরামিতিগুলি alচ্ছিক হিসাবে ঘোষণা করা যেতে পারে:

স্থির-পরামিতি:
    বৈশিষ্ট্যগুলি অপ্ট প্যারামিটার-সংশোধক বিকল্প প্রকার সনাক্তকারী ডিফল্ট-যুক্তি অপ্ট
ডিফল্ট-যুক্তি:
    = অভিব্যক্তি

  • একটি নির্দিষ্ট পরামিতি একটি সঙ্গে ডিফল্ট-যুক্তি একটি হল ঐচ্ছিক প্যারামিটার , যেহেতু একটি নির্দিষ্ট পরামিতি একটি ছাড়া ডিফল্ট-যুক্তি একটি হল প্রয়োজনীয় পরামিতি
  • আনুষ্ঠানিক-পরামিতি-তালিকায় একটি প্রয়োজনীয় প্যারামিটার চ্ছিক প্যারামিটারের পরে উপস্থিত হতে পারে না ।
  • একটি refবা outপ্যারামিটারে একটি ডিফল্ট-আর্গুমেন্ট থাকতে পারে না ।

বিকল্পভাবে, আপনি একটি রেফ / আউট প্যারামিটার দিয়ে একটি ওভারলোড তৈরি করতে পারেন। হ্যাঁ, আপনার দুটি ফাংশন সংজ্ঞা থাকবে, তবে এটি আপনার পরে যা ঘটবে তা সম্পাদন করবে
চাদ

201

না।

একটি workaround হ'ল / পদ্ধতির পরামিতি নেই এবং অন্যটি পদ্ধতিতে ওভারলোড হ'ল , যা কেবল আপনার বর্তমান পদ্ধতিটিকে কল করে।

public bool SomeMethod(out string input)
{
    ...
}

// new overload
public bool SomeMethod()
{
    string temp;
    return SomeMethod(out temp);
}

আপডেট: আপনার যদি সি # 7.0 থাকে তবে আপনি সহজ করতে পারেন:

// new overload
public bool SomeMethod()
{
    return SomeMethod(out _);    // declare out as an inline discard variable
}

(এটি নির্দেশ করার জন্য ধন্যবাদ @ অস্কার / @ রেইনার।)


6
টেম্প / ডামি ঘোষণার চেয়ে আরও মার্জিত সমাধানের জন্য কোনও ধারণা?
লুই রাইস

20
কি সম্পর্কে মার্জিত না? আমার কাছে পুরোপুরি শালীন দেখায়।
নিউট্রিনো

27
সম্ভবত শালীন, তবে মার্জিত অবশ্যই অন্য একটি লিগে রয়েছে। এর চেয়ে ভাল সমাধানের আর কোনও অর্থ এই নয় যে এটি ডিক্রি অনুসারে অত্যাধুনিক।
o0 '

7
@ O0 ধরে থাকুন। সি # 7.0 আপনি এই কাজ করতে সক্ষম হবে: return SomeMethod(out string temp)। : আরও এখানে দেখুন blogs.msdn.microsoft.com/dotnet/2016/08/24/...
অস্কার

7
সি # 7.0 আপনি মত একটি অস্থায়ী লেখ কেবল-পরিবর্তনশীল ব্যবহার করতে পারেন:return SomeMethod(out _);
Reiner

64

না, তবে আরেকটি দুর্দান্ত বিকল্প পদ্ধতিটি হ'ল asচ্ছিক প্যারামিটারগুলির জন্য জেনেরিক টেম্পলেট শ্রেণিটি নিম্নরূপে ব্যবহার করুন:

public class OptionalOut<Type>
{
    public Type Result { get; set; }
}

তারপরে আপনি এটি নীচে ব্যবহার করতে পারেন:

public string foo(string value, OptionalOut<int> outResult = null)
{
    // .. do something

    if (outResult != null) {
        outResult.Result = 100;
    }

    return value;
}

public void bar ()
{
    string str = "bar";

    string result;
    OptionalOut<int> optional = new OptionalOut<int> ();

    // example: call without the optional out parameter
    result = foo (str);
    Console.WriteLine ("Output was {0} with no optional value used", result);

    // example: call it with optional parameter
    result = foo (str, optional);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);

    // example: call it with named optional parameter
    foo (str, outResult: optional);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
}

19
এটি একটি খুব যুক্তিসঙ্গত সমাধান, তবে একটি বিষয় সম্পর্কে সচেতন হওয়া উচিত যে কম্পাইলারটি পদ্ধতিটি থেকে বেরিয়ে আসার আগে আউট প্যারামিটার নির্ধারিত প্রয়োজনীয়তা প্রয়োগ করবে না।
কেন স্মিথ

2
আমি এটি পছন্দ করি তবে আপনি যদি একটি নতুন শ্রেণি তৈরি করতে না চান তবে আপনি একটি একক উপাদান অ্যারে পেরিয়ে তা অনুকরণ করতে পারেন।
zumalifeguard

30

এটি করার একটি উপায় আসলে আছে যা সি # দ্বারা অনুমোদিত। এটি C ++ এ ফিরে আসে, এবং বরং সি # এর সুন্দর অবজেক্ট-ওরিয়েন্টড কাঠামো লঙ্ঘন করে।

এই পদ্ধতিটি সতর্কতার সাথে ব্যবহার করুন!

Youচ্ছিক প্যারামিটার দিয়ে আপনি নিজের ফাংশনটি ঘোষণা এবং লেখার উপায় এখানে:

unsafe public void OptionalOutParameter(int* pOutParam = null)
{
    int lInteger = 5;
    // If the parameter is NULL, the caller doesn't care about this value.
    if (pOutParam != null) 
    { 
        // If it isn't null, the caller has provided the address of an integer.
        *pOutParam = lInteger; // Dereference the pointer and assign the return value.
    }
}

তারপরে এইভাবে ফাংশনটি কল করুন:

unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.

এটি সঙ্কলন করতে পেতে, আপনাকে প্রকল্প বিকল্পগুলিতে অনিরাপদ কোড সক্ষম করতে হবে। এটি একটি সত্যই হ্যাকি সমাধান যা সাধারণত ব্যবহার করা উচিত নয়, তবে আপনি যদি কিছু অদ্ভুত, আরকেন, রহস্যময়, পরিচালনা-অনুপ্রেরণামূলক সিদ্ধান্তের জন্য সত্যিই সি # তে একটি alচ্ছিক আউট প্যারামিটার প্রয়োজন, তবে এটি আপনাকে ঠিক এটি করতে অনুমতি দেবে।


6

আইসিওয়াইএমআই: এখানে গণনা করা সি # 7.0 এর জন্য নতুন বৈশিষ্ট্যগুলি অন্তর্ভুক্ত করা হয়েছে , "তাত্পর্য" এখন একটি _ আকারে প্যারামিটার হিসাবে অনুমোদিত, আপনাকে প্যারামিটারগুলি অবহেলা করতে দেয় যাতে আপনার যত্ন নেই:

p.GetCoordinates(out var x, out _); // I only care about x

পিএস যদি আপনি "আউট ভার এক্স" অংশটি নিয়ে বিভ্রান্ত হন তবে লিংকে "আউট ভেরিয়েবলস" সম্পর্কে নতুন বৈশিষ্ট্যটিও পড়ুন।


এটি কি _ বা * "পি.গেটকর্ডিনেটস (আউট এক্স, এক্স * আউট *); // আমি কেবল এক্স এর জন্য যত্নশীল"
ওনুর টোপাল

দেখে মনে হচ্ছে আমি নথির পুরানো সংস্করণটি খুঁজছি।
ওনুর টোপাল

2

না, তবে আপনি Actionবিকল্প হিসাবে কোনও প্রতিনিধি (উদাহরণ ) ব্যবহার করতে পারেন ।

রবিন আর এর উত্তরে কিছুটা অনুপ্রাণিত হয়ে এমন পরিস্থিতির মুখোমুখি হয়েছিল যখন আমি ভেবেছিলাম যে আমি একটি optionচ্ছিক প্যারামিটার চাইছি, পরিবর্তে আমি একটি Actionপ্রতিনিধি ব্যবহার করেছি । Action<int>পার্থক্য এবং সাদৃশ্য দেখানোর জন্য ব্যবহারের জন্য পরিবর্তন করতে আমি তার উদাহরণ কোড ধার নিয়েছি :

public string foo(string value, Action<int> outResult = null)
{
    // .. do something

    outResult?.Invoke(100);

    return value;
}

public void bar ()
{
    string str = "bar";

    string result;
    int optional = 0;

    // example: call without the optional out parameter
    result = foo (str);
    Console.WriteLine ("Output was {0} with no optional value used", result);

    // example: call it with optional parameter
    result = foo (str, x => optional = x);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);

    // example: call it with named optional parameter
    foo (str, outResult: x => optional = x);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
}

এটির সুবিধাটি রয়েছে যে sourceচ্ছিক পরিবর্তনশীল উত্সটিতে একটি সাধারণ int হিসাবে উপস্থিত হয় (সংকলকটি এটি একটি ক্লোজার ক্লাসে গুটিয়ে রাখে, পরিবর্তে আমাদের এটি ব্যবহারকারী-সংজ্ঞায়িত শ্রেণিতে স্পষ্টভাবে আবৃত করে)।

চলকটির সুস্পষ্ট সূচনা প্রয়োজন কারণ সংকলকটি ধরে নিতে পারে না যে Actionফাংশন কলটি প্রস্থান করার আগে ডাকা হবে।

এটি সমস্ত ব্যবহারের ক্ষেত্রে উপযুক্ত নয়, তবে আমার আসল ব্যবহারের ক্ষেত্রে (একটি ফাংশন যা ইউনিট পরীক্ষার জন্য ডেটা সরবরাহ করে এবং যেখানে কোনও নতুন ইউনিট পরীক্ষার জন্য কিছু অভ্যন্তরীণ অবস্থানে রিটার্নের মান উপস্থিত না হওয়া প্রয়োজন ছিল) এর জন্য ভাল কাজ করেছে।


0

সি # 6.0 এবং নিম্নের জন্য আউট প্যারামিটারটির সাথে কল করতে আউট প্যারামিটার ছাড়াই একটি ওভারলোডেড পদ্ধতি ব্যবহার করুন। আমি নিশ্চিত না কেন .NET কোর এর জন্য একটি সি # 7.0 কেন এই থ্রেডের জন্য এমনকি সঠিক উত্তর যখন যখন এটি নির্দিষ্টভাবে জিজ্ঞাসা করা হয়েছিল যে সি # 4.0 এর একটি outচ্ছিক প্যারামিটার থাকতে পারে কিনা। উত্তর নেই!


-2

এরকম কি হবে?

public bool OptionalOutParamMethod([Optional] ref string pOutParam)
{
    return true;
}

আপনাকে এখনও সি # থেকে প্যারামিটারে একটি মান দিতে হবে তবে এটি একটি alচ্ছিক রেফ প্যারাম।


8
"আপনাকে সি # থেকে প্যারামিটারে এখনও একটি মান দিতে হবে" ... এটি optionচ্ছিক নয়।
আর্তুরো টরেস সানচেজ

সি # টীকাটিকে উপেক্ষা করে [Optional]। এটি কোনও উপকারে আসে না।
টুলমেকারস্টেভ

-4
void foo(ref int? n)
{
    return null;
}

1
প্রত্যেককে ধারণাটি সহজেই বোঝার জন্য দয়া করে আপনার
কোডটিতে

1
যদিও এই কোডটি প্রশ্নের উত্তর দিতে পারে, কেন এবং / অথবা এটি কীভাবে প্রশ্নের উত্তর দেয় সে সম্পর্কিত অতিরিক্ত প্রসঙ্গ সরবরাহ করে এর দীর্ঘমেয়াদী মানকে উল্লেখযোগ্যভাবে উন্নতি করবে। কিছু ব্যাখ্যা যুক্ত করতে দয়া করে আপনার উত্তরটি সম্পাদনা করুন।
টবি স্পিড

2
পদ্ধতির শূন্য রিটার্নের ধরণ হওয়ায় এটি একটি সিনট্যাক্স ত্রুটির ফলে ঘটবে। এছাড়াও, প্রশ্নের উত্তর দেয় না।
নাথান মন্টেজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.