'রেফ' এবং 'আউট' কীওয়ার্ডগুলির মধ্যে পার্থক্য কী?


891

আমি একটি ফাংশন তৈরি করছি যেখানে আমার কোনও অবজেক্টটি পাস করতে হবে যাতে এটি ফাংশনটির মাধ্যমে সংশোধন করা যায়। পার্থক্য কি:

public void myFunction(ref MyClass someClass)

এবং

public void myFunction(out MyClass someClass)

আমার কোনটি ব্যবহার করা উচিত এবং কেন?


69
আপনি: আমার কোনও বস্তু পাস করতে হবে যাতে এটি পরিবর্তন করা যায় এটি দেখে মনে হচ্ছে MyClassএটি কোনও classপ্রকার, অর্থাত্ একটি রেফারেন্স টাইপ। সেক্ষেত্রে আপনি যে অবজেক্টটি পাস করবেন myFunctionতা কোনও ref/ outকীওয়ার্ড না দিয়ে এমনকি সংশোধন করতে পারে । myFunctionএকটি নতুন রেফারেন্স পাবেন যা একই অবজেক্টের দিকে নির্দেশ করে এবং এটি একই বস্তুকে যতটা চায় তা পরিবর্তন করতে পারে। মূলশব্দটি যে পার্থক্যটি refতৈরি করবে তা হ'ল একই বস্তুর একই রেফারেন্স myFunctionপেয়েছে । এটি কেবল তখনই গুরুত্বপূর্ণ যখন রেফারেন্সটি অন্য কোনও বস্তুর প্রতি নির্দেশ করতে হবে । myFunction
জেপ্প স্টিগ নীলসেন

3
@ অ্যান্থনি কোলেসোভের পক্ষে যখন নিখুঁত হয় তবে আমি এখানে বিভ্রান্তিমূলক উত্তরের পরিমাণ নিয়ে হতবাক হয়েছি।
o0 '

আপনি একাধিক মান ফিরিয়ে দিতে কোনও পদ্ধতি চাইলে আউট পদ্ধতি ঘোষণা করা কার্যকর। একটি যুক্তি নাল বরাদ্দ করা যেতে পারে। এটি বিকল্পগুলিকে মানগুলি ফিরিয়ে আনতে সক্ষম করে।
ইয়েগ্রাফ আন্দ্রেয়েভিচ ঝিভাগো

এখানে উদাহরণ এটা আরো বোধগম্য :) ব্যাখ্যা dotnet-tricks.com/Tutorial/csharp/...
Prageeth godage

2
@ জেপিস্টিগনিয়েলসনের মন্তব্য, প্রযুক্তিগতভাবে, ওপি-র আসল প্রশ্নের সঠিক উত্তর (কেবলমাত্র)। কোনও পদ্ধতিতে কোনও বস্তুটি পাস করার জন্য যাতে পদ্ধতিটি বস্তুটি সংশোধন করতে পারে , কেবলমাত্র মান দ্বারা পদ্ধতিতে ((রেফারেন্স)) বস্তুটি পাস করুন। অবজেক্ট আর্গুমেন্টের মাধ্যমে পদ্ধতির মধ্যে অবজেক্ট পরিবর্তন করা মূল অবজেক্টটি পরিবর্তিত করে , যদিও পদ্ধতিটির নিজস্ব পৃথক ভেরিয়েবল রয়েছে (যা একই বস্তুর উল্লেখ করে)।
ডেভিড আর ট্রিবিলে

উত্তর:


1158

refকম্পাইলারকে বলে যে ফাংশনে প্রবেশের আগে অবজেক্টটি আরম্ভ করা হয়েছে, এবং outসংকলককে বলে যে ফাংশনের ভিতরে অবজেক্টটি আরম্ভ করা হবে।

সুতরাং refদ্বিমুখী হলেও , outকেবলমাত্র বাইরে।


269
আউট নির্দিষ্ট করার জন্য অন্য একটি দুর্দান্ত জিনিস হ'ল ফাংশনটি আউট প্যারামিটারে বরাদ্দ করতে হয়। এটিকে এটি ছাড়াই ছাড়ার অনুমতি নেই।
ড্যানিয়েল আরউইকার

7
'রেফ' কি কেবল মূল্য ধরণের ক্ষেত্রে প্রযোজ্য? যেহেতু রেফারেন্সের ধরণটি সর্বদা রেফ দিয়ে যায়।
ত্রুটিযুক্ত

3
হ্যাঁ. স্ট্রাক্ট সহ মান ধরণের
রুন গ্রিমস্টাড

17
@ ফাল্টি: না, রেফ কেবল মান ধরণের ক্ষেত্রে প্রযোজ্য নয়। রেফ / আউট সি / সি ++ এর পয়েন্টারগুলির মতো, তারা সরাসরি অবজেক্টের পরিবর্তে অবজেক্টের মেমোরি অবস্থানের সাথে (অপ্রত্যক্ষভাবে সি # তে) ডিল করে।
THR

52
@ ফাল্টি: পাল্টে, রেফারেন্সের ধরণগুলি সর্বদা সি # তে মান দ্বারা প্রেরণ করা হয়, যদি না আপনি রেফার স্পেসিফায়ার ব্যবহার করেন। যদি আপনি মাইভাল = কোনওভাবেই সেট করেন তবে প্রভাবটি কেবলমাত্র সেই ফাংশনের সুযোগে। রেফ কীওয়ার্ডটি আপনাকে মাইভালটিকে কোনওরকমের দিকে চিহ্নিত করার অনুমতি দেয়।
জেসনট্রু

534

refপরিবর্তক মানে যে:

  1. মান ইতিমধ্যে সেট করা হয়েছে এবং
  2. পদ্ধতিটি এটি পড়তে এবং সংশোধন করতে পারে।

outপরিবর্তক মানে যে:

  1. মান সেট করা নেই এবং সেট না করা পর্যন্ত পদ্ধতি দ্বারা এটি পড়া যায় না ।
  2. পদ্ধতিটি অবশ্যই এটি ফিরে আসার আগে সেট করে।

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

5
এমএসডিএন থেকে: একটি রেফ প্যারামিটার ব্যবহারের আগে শুরু করতে হবে, যখন একটি আউট প্যারামিটার স্পষ্টভাবে আরম্ভ করার আগে পাস করার আগে কোনও পূর্ববর্তী মানকে উপেক্ষা করা উচিত নয়।
শিব কুমার

1
এর সাথে out, পদ্ধতিটি নির্ধারণের আগে, পদ্ধতিটি বলার আগে যদি এটি আরম্ভ করা হয়ে থাকে, তবে কী এটি পদ্ধতিটির মধ্যে আদৌ পড়া যায়? আমি বলতে চাইছি, কলিং পদ্ধতিটি আর্গুমেন্ট হিসাবে কলিং পদ্ধতিটি কী পাস করেছিল তা পড়তে পারে?
Panzercrisis

3
Panzercrisis, "আউট" এর জন্য, তথাকথিত পদ্ধতিটি এটি ইতিমধ্যে সেট করা থাকলে পড়তে পারে। তবে এটি আবার সেট করতে হবে।
রবার্ট jebakumar2

146

ধরা যাক ডম টিপিএস রিপোর্টগুলির মেমো সম্পর্কে পিটারের কিউবিকেলে দেখায়।

ডম যদি রেফ আর্গুমেন্ট হয় তবে তার কাছে মেমোটির একটি মুদ্রিত অনুলিপি থাকবে।

ডম যদি কোনও বাহ্য যুক্তি হয়ে থাকে তবে তিনি পিটারকে তাঁর সাথে রাখার জন্য মেমোটির একটি নতুন অনুলিপি মুদ্রণ করতে চাইবেন।


54
রেফ ডোম এই প্রতিবেদনটি পেন্সিলটিতে লিখতেন যাতে পিটার এটি সংশোধন করতে পারে
ডিবেস্টার

6
@ ডিবিস্টার আপনি জানেন, রূপকটি কখনও আপনার কিছুই করেনি, কেন আপনি এটিকে অত্যাচার করবেন? ;)
মাইকেল ব্ল্যাকবার্ন

21
বিনোদনমূলক এখনও শিক্ষামূলক,
স্ট্যাকওভারফ্লো এর

2
যদি কেউ এই উত্তরটিকে কেবলমাত্র অর্ধ-মজার সন্ধান করে তবে দয়া করে "অফিস স্পেস" মুভিটি দেখুন।
ডিসপ্লেনেম

এবং ডম এবং পিটারস বস দমকে দাঁড় করিয়েছিলেন (তর্ক হিসাবে), দু'জনকেই নতুনভাবে মুদ্রণের কাজ করতে বাধ্য করেছিলেন যতক্ষণ না পিটার হাতের মুদ্রণ প্রিন্ট আউট করে
প্যাট্রিক আর্টনার

57

আমি একটি ব্যাখ্যায় আমার হাত চেষ্টা করতে যাচ্ছি:

আমি মনে করি আমরা বুঝতে পারি যে মানগুলি কীভাবে সঠিকভাবে কাজ করে? মান প্রকারগুলি (int, দীর্ঘ, কাঠামো ইত্যাদি)। যখন আপনি এগুলি কোনও রেফ-কমান্ড ব্যতীত কোনও ফাংশনে প্রেরণ করেন এটি ডেটা কপি করে । ফাংশনে সেই ডেটাতে আপনি যে কিছু করেন তা কেবল অনুলিপিটিকেই প্রভাবিত করে, মূলটি নয়। রেফ কমান্ড ACTUAL ডেটা প্রেরণ করে এবং যে কোনও পরিবর্তন ফাংশনের বাইরে থাকা ডেটাগুলিকে প্রভাবিত করবে।

বিভ্রান্তিকর অংশে ঠিক আছে, রেফারেন্স ধরণের:

একটি রেফারেন্স প্রকার তৈরি করতে দেয়:

List<string> someobject = new List<string>()

আপনি যখন কোনও নতুন স্থাপন করেন , দুটি অংশ তৈরি করা হয়:

  1. মেমোরির ব্লক যা কোনওরকমের জন্য ডেটা ধারণ করে ।
  2. ডেটা যে ব্লক একটি রেফারেন্স (পয়েন্টার)।

এখন আপনি কখন পাঠাবো someobject এটা সুত্র অনুলিপি ছাড়া একটি পদ্ধতি মধ্যে রেফারেন্স পয়েন্টার, ডেটা নেই। সুতরাং আপনার এখন এটি আছে:

(outside method) reference1 => someobject
(inside method)  reference2 => someobject

দুটি একই রেফারেন্স একই অবজেক্টের দিকে নির্দেশ করছে। আপনি যদি রেফারেন্স 2 ব্যবহার করে কোনও সম্পত্তিতে কোনও সম্পত্তি পরিবর্তন করেন তবে এটি রেফারেন্স 1 দ্বারা নির্দেশিত একই ডেটাটিকে প্রভাবিত করবে।

 (inside method)  reference2.Add("SomeString");
 (outside method) reference1[0] == "SomeString"   //this is true

আপনি যদি রেফারেন্স 2 বাতিল করে দেন বা নতুন ডেটাতে এটি নির্দেশ করেন তবে এটি রেফারেন্স 1 এবং ডেটা রেফারেন্স 1 কে পয়েন্ট করবে না।

(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true

The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject

এখন আপনি কোনও পদ্ধতিতে রেফ দ্বারা কোনও স্থানে পাঠানোর সময় কী হবে ? প্রকৃত রেফারেন্স করার someobject পদ্ধতিতে পাঠানো হয়। সুতরাং আপনার কাছে এখন কেবলমাত্র ডেটা সম্পর্কিত একটি উল্লেখ রয়েছে:

(outside method) reference1 => someobject;
(inside method)  reference1 => someobject;

কিন্তু এটার মানে কি? এটি দুটি প্রধান বিষয় ব্যতীত রেফ দ্বারা না করে কোনও পাঠানোর মতোই কাজ করে:

1) আপনি যদি পদ্ধতির অভ্যন্তরে রেফারেন্সটি বাতিল করেন তবে এটি পদ্ধতির বাইরে থাকা শূন্য করে দেবে।

 (inside method)  reference1 = null;
 (outside method) reference1 == null;  //true

2) আপনি এখন সম্পূর্ণ ভিন্ন ডেটা অবস্থানের রেফারেন্সটি নির্দেশ করতে পারেন এবং ফাংশনের বাইরের রেফারেন্সটি এখন নতুন ডেটা অবস্থানের দিকে নির্দেশ করবে।

 (inside method)  reference1 = new List<string>();
 (outside method) reference1.Count == 0; //this is true

আপনি সর্বোপরি বোঝাতে চেয়েছেন (রেফের ক্ষেত্রে) কেবলমাত্র তথ্যের জন্য একটি রেফারেন্স রয়েছে তবে এর জন্য দুটি উপন্যাস। রাইট?
সাদিক

3
পরিষ্কার ব্যাখ্যা জন্য upvated। কিন্তু আমি মনে করি এই প্রশ্নের উত্তর দিতে নয়, যেমন মধ্যে পার্থক্য ব্যাখ্যা না refএবং outপ্যারামিটার।
জয়স বাবু

1
অ্যামেজিং। আপনি outকিওয়ার্ড হিসাবে একই ব্যাখ্যা করতে পারেন ?
আসিফ মোশতাক

28

রেফ ভিতরে এবং বাইরে আছে

outআপনার প্রয়োজনীয়তার জন্য যেখানেই এটি পর্যাপ্ত থাকে তবে আপনার পছন্দ হিসাবে ব্যবহার করা উচিত ।


যথেষ্ট নয়, গ্রহণযোগ্য উত্তর হিসাবে যদি নির্দেশিত এবং অকেজো মূল্য-প্রকারগুলি অগ্রাহ্য না করা হয় তবে তা ব্যর্থ হয়ে যায়।
কেনি

@ ক্যান্নি: আপনি কি দয়া করে কিছুটা স্পষ্ট করে বলতে পারেন - অর্থাত্ উত্তরের মনোভাব বজায় রাখতে আপনি কোন শব্দটি পরিবর্তন করবেন তবে আপনি যে অনিশ্চয়তা দেখছেন তা সরিয়ে দেবেন? আমার উত্তরটি কোনও নবজাতকের কাছ থেকে অনুমান করা অনুমান নয়, তবে আপনার মন্তব্যে তাড়াতাড়ি (নিখরচায়, টাইপোস) মনে হচ্ছে এটি এটি। উদ্দেশ্যটি হ'ল ন্যূনতম সংখ্যার সাথে পার্থক্য সম্পর্কে চিন্তাভাবনার একটি উপায় সরবরাহ করা।
রুবেন বারটেলিংক

(বিটিডব্লিউ আমি মান ধরণের, রেফারেন্সের ধরণের সাথে, রেফারেন্সের মাধ্যমে প্রেরণকারী, মান দ্বারা
প্রেরণকারী, সিওএম

1
অবজেক্ট রেফারেন্সগুলি মান দ্বারা পাস হয় ("রেফ" বা "আউট" কীওয়ার্ড ব্যবহার করার সময় ব্যতীত)। আইডি নম্বর হিসাবে বস্তু চিন্তা করুন। যদি কোনও শ্রেণি ভেরিয়েবল "অবজেক্ট # 1943" ধারণ করে এবং একটি সেই রুটিনের মান অনুসারে সেই পরিবর্তনশীলটিকে পাস করে, সেই রুটিনটি বস্তু # 1943 এ পরিবর্তন করতে পারে, তবে এটি "অবজেক্ট # 1943" ব্যতীত অন্য কিছুতে ভেরিয়েবল পয়েন্ট করতে পারে না। যদি ভেরিয়েবলটি রেফারেন্স দিয়ে পাস করা হয় তবে রুটিন চলক পয়েন্টটিকে "অবজেক্ট # 5441" ধরে রাখতে পারে।
সুপারক্যাট

1
@ সুপের্যাট: রেফ বনাম ভাল (এবং এই ফলোআপ অ্যানাওলজি) সম্পর্কে আপনার ব্যাখ্যাটি আমি পছন্দ করি। আমি মনে করি ক্যানির আসলে তাকে বোঝানো এগুলির কোনও দরকার নেই, (তুলনামূলকভাবে) তাঁর মন্তব্যগুলি যেমন বিভ্রান্তিকর ছিল। আমি আশা করি আমরা সবাই এই গড্ডাম মন্তব্যগুলি সরিয়ে ফেলতে পারি যদিও তারা সবাইকে বিভ্রান্ত করছে। এই সমস্ত বাজে কথাটির মূল কারণটি মনে হয় যে কেনি আমার উত্তরটি ভুল বুঝে লিখেছিল এবং এখনও একটি শব্দও উল্লেখ করতে পারে যা যুক্ত / সরানো / প্রতিস্থাপন করা উচিত। আমরা তিনজনের কেউই যে আলোচনাটি ইতিমধ্যে জানতাম না, সেখান থেকে আমরা কিছুই জানতে পারি নি এবং অন্য উত্তরের একটি হাস্যকর সংখ্যা রয়েছে up
রুবেন বারটেলিংক

18

আউট:

সি # তে, একটি পদ্ধতি কেবল একটি মান ফেরত দিতে পারে। আপনি যদি একাধিক মান ফিরিয়ে দিতে চান তবে আপনি আউট কীওয়ার্ডটি ব্যবহার করতে পারেন। রিটার্ন-বাই-রেফারেন্স হিসাবে আউট মডিফায়ার রিটার্ন। সহজ উত্তরটি হ'ল পদ্ধতিটি থেকে মানটি পেতে কী শব্দটি "আউট" ব্যবহার করা হয়।

  1. কলিং ফাংশনটিতে আপনাকে মানটি আরম্ভ করার দরকার নেই।
  2. আপনাকে অবশ্যই ডাকা ফাংশনে মান নির্ধারণ করতে হবে, অন্যথায় সংকলক একটি ত্রুটির প্রতিবেদন করবে।

সুত্র:

সি # তে, আপনি যখন পদ্ধতির প্যারামিটারের যুক্তি হিসাবে কোনও মান টাইপ যেমন ইন্ট, ফ্লোট, ডাবল ইত্যাদি পাস করেন, তখন এটি মান দ্বারা পাস হয় passed অতএব, আপনি যদি প্যারামিটারের মানটি সংশোধন করেন তবে এটি পদ্ধতি কলটিতে যুক্তিকে প্রভাবিত করে না। আপনি যদি "রেফ" কীওয়ার্ড দিয়ে প্যারামিটারটি চিহ্নিত করেন তবে এটি আসল ভেরিয়েবলে প্রতিফলিত হবে।

  1. ফাংশনটি কল করার আগে আপনাকে পরিবর্তনশীলটি শুরু করতে হবে।
  2. পদ্ধতিতে রেফ প্যারামিটারের কোনও মান নির্ধারণ করা বাধ্যতামূলক নয়। আপনি যদি মানটি পরিবর্তন না করেন তবে এটিকে "রেফ" হিসাবে চিহ্নিত করার দরকার কী?

"সি # তে একটি পদ্ধতি কেবল একটি মান ফেরত দিতে পারে you আপনি যদি একাধিক মান ফেরত দিতে চান তবে আপনি আউট কীওয়ার্ডটি ব্যবহার করতে পারেন।" আমরা মান ফেরত দেওয়ার জন্য "রেফ" ব্যবহার করতে পারি। সুতরাং আমরা কোনও পদ্ধতি থেকে একাধিক মান ফিরিয়ে দিতে চাইলে আমরা রেফ এবং আউট উভয়ই ব্যবহার করতে পারি?
নেড

1
সি # 7 এ আপনি ValueTuples সহ একাধিক মান ফিরিয়ে দিতে পারেন।
manমান বাহরামপুর

13

কুকুরটিকে প্রসারিত করা, বিড়ালের উদাহরণ। রেফ সহ দ্বিতীয় পদ্ধতি কলারের দ্বারা রেফারেন্স করা অবজেক্টটিকে পরিবর্তন করে। তাই "বিড়াল" !!!

    public static void Foo()
    {
        MyClass myObject = new MyClass();
        myObject.Name = "Dog";
        Bar(myObject);
        Console.WriteLine(myObject.Name); // Writes "Dog". 
        Bar(ref myObject);
        Console.WriteLine(myObject.Name); // Writes "Cat". 
    }

    public static void Bar(MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

    public static void Bar(ref MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

8

যেহেতু আপনি একটি রেফারেন্স টাইপ (একটি শ্রেণি) দিয়ে যাচ্ছেন সেখানে কোনও ব্যবহারের প্রয়োজন নেই refকারণ ডিফল্ট হিসাবে কেবল প্রকৃত অবজেক্টের একটি রেফারেন্স পাস হয় এবং তাই আপনি সর্বদা রেফারেন্সের পিছনে অবজেক্টটি পরিবর্তন করেন।

উদাহরণ:

public void Foo()
{
    MyClass myObject = new MyClass();
    myObject.Name = "Dog";
    Bar(myObject);
    Console.WriteLine(myObject.Name); // Writes "Cat".
}

public void Bar(MyClass someObject)
{
    someObject.Name = "Cat";
}

যতক্ষণ আপনি কোনও ক্লাসে পাস করেন আপনি refযদি আপনার পদ্ধতির অভ্যন্তরে অবজেক্টটি পরিবর্তন করতে চান তবে আপনাকে ব্যবহার করতে হবে না ।


5
কোনও নতুন অবজেক্ট তৈরি না করে এবং ফিরে না আসলে এটি কাজ করে। একটি নতুন অবজেক্ট তৈরি করা হলে, পুরানো বস্তুর রেফারেন্স হারিয়ে যাবে।
त्সুবা

8
এটি ভুল - নিম্নলিখিত চেষ্টা করুন: সম্পাদন শেষ someObject = nullকরতে যোগ করুন Bar। আপনার কোডটি সূক্ষ্মভাবে চলবে কারণ কেবলমাত্র Barউদাহরণটির উল্লেখটি নল করা হয়েছিল। এখন এটিকে পরিবর্তন Barকরুন Bar(ref MyClass someObject)এবং আবার সম্পাদন করুন - আপনি উদাহরণটি পেয়ে যাবেন NullReferenceExceptionকারণ Fooএর উল্লেখটিও নালু হয়ে গেছে।
কিথ

8

refএবং outনিম্নলিখিত পার্থক্য বাদে একইরকম আচরণ করুন।

  • refভেরিয়েবল ব্যবহারের আগে শুরু করা আবশ্যক। outভেরিয়েবল অ্যাসাইনমেন্ট ছাড়াই ব্যবহার করা যেতে পারে
  • outপ্যারামিটারটি অবশ্যই এটি ব্যবহার করে এমন ফাংশন দ্বারা একটি অ-সাইন করা মান হিসাবে গণ্য করতে হবে। সুতরাং, আমরা outকলিং কোডটিতে প্রাথমিক পরামিতি ব্যবহার করতে পারি , তবে ফাংশনটি কার্যকর হলে মানটি হারাবে।

8

উদাহরণস্বরূপ যারা শিখেন তাদের জন্য (আমার মতো) অ্যান্টনি কোলেসভ কী বলছেন তা এখানে ।

আমি রেফ, আউট এবং অন্যদের ন্যূনতম উদাহরণ তৈরি করেছি পয়েন্টটি চিত্রিত করার জন্য। আমি সেরা অভ্যাসগুলি আবরণ করছি না, কেবলমাত্র পার্থক্যগুলি বোঝার জন্য উদাহরণ।

https://gist.github.com/2upmedia/6d98a57b68d849ee7091


6

"বেকার"

কারণ প্রথমটি আপনার স্ট্রিং-রেফারেন্সটিকে "বেকার" এ নির্দেশ করে। রেফারেন্স পরিবর্তন করা সম্ভব কারণ আপনি এটিকে রেফ কীওয়ার্ডের মাধ্যমে পাস করেছেন (=> স্ট্রিংয়ের কোনও রেফারেন্সের রেফারেন্স)। দ্বিতীয় কল স্ট্রিংয়ের রেফারেন্সের একটি অনুলিপি পায়।

স্ট্রিং প্রথমে এক ধরণের বিশেষ দেখায়। তবে স্ট্রিংটি কেবল একটি রেফারেন্স ক্লাস এবং যদি আপনি সংজ্ঞা দেন

string s = "Able";

তারপরে স্ট্রিং ক্লাসের একটি উল্লেখ যা "সক্ষম" পাঠ্য ধারণ করে! এর মাধ্যমে একই ভেরিয়েবলের জন্য আরও একটি অ্যাসাইনমেন্ট

s = "Baker";

মূল স্ট্রিংটি পরিবর্তন করে না তবে কেবল একটি নতুন উদাহরণ তৈরি করে এবং সেই উদাহরণটি দেখানো যাক!

আপনি নিম্নলিখিত সামান্য কোড উদাহরণ দিয়ে এটি ব্যবহার করতে পারেন:

string s = "Able";
string s2 = s;
s = "Baker";
Console.WriteLine(s2);

তুমি কি প্রত্যাশা কর? আপনি যা পাবেন তা এখনও "সক্ষম" কারণ আপনি সুনির্দিষ্টভাবে উদাহরণটিকে অন্য উদাহরণে সেট করেছেন যখন এস 2 মূল উদাহরণটির সাথে নির্দেশ করে।

সম্পাদনা: স্ট্রিংটিও অপরিবর্তনীয় যার অর্থ হ'ল কোনও পদ্ধতি বা সম্পত্তি নেই যা বিদ্যমান স্ট্রিংয়ের উদাহরণটি সংশোধন করে (আপনি ডক্সে একটি সন্ধান করার চেষ্টা করতে পারেন তবে আপনি কোনও :-)কে জরিমানা করতে পারবেন না)। সমস্ত স্ট্রিং ম্যানিপুলেশন পদ্ধতি একটি নতুন স্ট্রিং উদাহরণ দেয়! (এজন্য আপনি স্ট্রিংবিল্ডার ক্লাসটি ব্যবহার করার সময় প্রায়শই ভাল পারফরম্যান্স পান)


1
যথাযথভাবে। সুতরাং এটি বলা শক্তভাবে সত্য নয় যেহেতু "যেহেতু আপনি একটি রেফারেন্স টাইপ (একটি শ্রেণি) দিয়ে যাচ্ছেন সেখানে কোনও রেফ ব্যবহারের দরকার নেই"।
পল মিশেল

তাত্ত্বিকভাবে এটি বলা ঠিক কারণ তিনি লিখেছিলেন "যাতে এটি পরিবর্তন করা যায়" যা স্ট্রিংয়ে সম্ভব নয়। কিন্তু অপরিবর্তনীয় বস্তুর কারণে "রেফ" এবং "আউট" রেফারেন্স ধরণের জন্যও খুব দরকারী! (.নেটে প্রচুর অপরিবর্তনীয় ক্লাস রয়েছে!)
মিমি মিমি মিমি

হ্যাঁ আপনি ঠিক. আমি স্ট্রিংয়ের মতো অপরিবর্তনীয় বস্তুর কথা ভাবি নি কারণ বেশিরভাগ বস্তু পরিবর্তনীয়।
অ্যালবিক

1
ভাল, নিশ্চিত হওয়ার জন্য, এটি এলকিউপিতে দেখার জন্য একটি বিস্ময়কর উত্তর; এতে অন্যায় করার কিছুই নেই, তবে এটি অন্য কোনও মন্তব্যে দীর্ঘ এবং পুরোপুরি প্রতিক্রিয়া বলে মনে হচ্ছে (যেহেতু মূল প্রশ্নটি তার কোনও সংশোধনীতে সক্ষম এবং বাকের উল্লেখ করেছে), যদিও এটি একটি ফোরাম ছিল। আমি অনুমান করি যে সত্যিকার অর্থে এখনও বেরিয়ে আসেনি when
নাথন টগি

6

রেফের অর্থ রেফ প্যারামিটারের মানটি ইতিমধ্যে সেট করা আছে, পদ্ধতিটি এটি পড়তে এবং সংশোধন করতে পারে। রেফার কীওয়ার্ডটি ব্যবহার করা একই বলে যে কলারটি প্যারামিটারটির মান শুরু করার জন্য দায়ী।


আউট কম্পাইলারকে বলে যে অবজেক্টের সূচনাটি ফাংশনের দায়িত্ব, ফাংশনটিকে আউট প্যারামিটারে বরাদ্দ করতে হবে। এটিকে এটি ছাড়াই ছাড়ার অনুমতি নেই।


5

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

নিম্নলিখিত উদাহরণে এই প্রকাশ:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValue(out int x )
      {
         int temp = 5;
         x = temp;
      }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* local variable definition */
         int a = 100;

         Console.WriteLine("Before method call, value of a : {0}", a);

         /* calling a function to get the value */
         n.getValue(out a);

         Console.WriteLine("After method call, value of a : {0}", a);
         Console.ReadLine();

      }
   }
}

রেফ: রেফারেন্স প্যারামিটার হল একটি ভেরিয়েবলের মেমরি অবস্থানের একটি রেফারেন্স। যখন আপনি রেফারেন্স অনুসারে প্যারামিটারগুলি পাস করেন, মান পরামিতিগুলির বিপরীতে, এই পরামিতিগুলির জন্য একটি নতুন স্টোরেজ অবস্থান তৈরি হয় না। রেফারেন্স প্যারামিটারগুলি পদ্ধতিতে সরবরাহ করা প্রকৃত পরামিতিগুলির সমান মেমরির অবস্থানকে উপস্থাপন করে।

সি # তে, আপনি রেফার কীওয়ার্ডটি ব্যবহার করে রেফারেন্স পরামিতিগুলি ঘোষণা করেন। নিম্নলিখিত উদাহরণটি এটি দেখায়:

using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(ref int x, ref int y)
      {
         int temp;

         temp = x; /* save the value of x */
         x = y;   /* put y into x */
         y = temp; /* put temp into y */
       }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* local variable definition */
         int a = 100;
         int b = 200;

         Console.WriteLine("Before swap, value of a : {0}", a);
         Console.WriteLine("Before swap, value of b : {0}", b);

         /* calling a function to swap the values */
         n.swap(ref a, ref b);

         Console.WriteLine("After swap, value of a : {0}", a);
         Console.WriteLine("After swap, value of b : {0}", b);

         Console.ReadLine();

      }
   }
}

4

রেফারেন্স এবং আউট আউট কাজ ঠিক রেফারেন্সগুলি দিয়ে যাওয়া এবং সি ++ এর মতো পয়েন্টারগুলি দিয়ে যাওয়ার মতো।

রেফের জন্য, যুক্তিটি অবশ্যই ঘোষণা করা এবং আরম্ভ করা উচিত।

বাহিরের জন্য, যুক্তিটি অবশ্যই ঘোষণা করতে হবে তবে শুরু হতে পারে বা নাও হতে পারে

        double nbr = 6; // if not initialized we get error
        double dd = doit.square(ref nbr);

        double Half_nbr ; // fine as passed by out, but inside the calling  method you initialize it
        doit.math_routines(nbr, out Half_nbr);

1
আপনি একটি পরিবর্তনশীল ইনলাইন ঘোষণা করতে পারেন: out double Half_nbr
সেবাস্তিয়ান হফম্যান

4

লেখার সময়:

(1) আমরা কলিং পদ্ধতি তৈরি করি Main()

(২) এটি একটি তালিকা অবজেক্ট তৈরি করে (যা একটি রেফারেন্স টাইপ অবজেক্ট) এবং এটি ভেরিয়েবলে সঞ্চয় করে myList

public sealed class Program 
{
    public static Main() 
    {
        List<int> myList = new List<int>();

রানটাইমের সময়:

(3) রানটাইম স্ট্যাকের জন্য # 00 এ একটি মেমরি বরাদ্দ করে, কোনও ঠিকানা সঞ্চয় করার জন্য যথেষ্ট প্রশস্ত (# 00 = myList, যেহেতু ভেরিয়েবলের নামগুলি মেমরির অবস্থানগুলির জন্য কেবলমাত্র পৃথক)

(4) রানটাইম মেমরি অবস্থান #FF এ হিপগুলিতে একটি তালিকা অবজেক্ট তৈরি করে (এই সমস্ত ঠিকানা উদাহরণস্বরূপ হ'ল)

(৫) রানটাইম তখন # 00 এ অবজেক্টের প্রারম্ভিক ঠিকানা #FF সংরক্ষণ করবে (বা কথায়, পয়েন্টারে তালিকার অবজেক্টের রেফারেন্স স্টোর করে myList)

লেখার সময়টিতে ফিরে যান:

()) এরপরে আমরা তালিকার অবজেক্টটিকে কল myParamListপদ্ধতির আর্গুমেন্ট হিসাবে পাস করি modifyMyListএবং এটিতে একটি নতুন তালিকা অবজেক্ট বরাদ্দ করি

List<int> myList = new List<int>();

List<int> newList = ModifyMyList(myList)

public List<int> ModifyMyList(List<int> myParamList){
     myParamList = new List<int>();
     return myParamList;
}

রানটাইমের সময়:

()) রানটাইম কল করা পদ্ধতির জন্য কল রুটিন শুরু করে এবং এর অংশ হিসাবে, পরামিতিগুলির ধরণটি পরীক্ষা করে।

(8) রেফারেন্সের ধরণটি সন্ধান করার পরে, এটি প্যারামিটার ভেরিয়েবলটি aliasing করার জন্য # 04 এ স্ট্যাকের উপর একটি মেমরি বরাদ্দ করে myParamList

(9) এটি এর পরে এটিতে #FF এর মানও সংরক্ষণ করে।

(10) রানটাইম মেমরি অবস্থান # 004 এ হিপগুলিতে একটি তালিকা অবজেক্ট তৈরি করে এবং # 04 এ এই মানটির সাথে প্রতিস্থাপিত করে (বা মূল তালিকার অবজেক্টটিকে অবলম্বন করে এবং এই পদ্ধতিতে নতুন তালিকা অবজেক্টের দিকে নির্দেশিত)

# 00 এ ঠিকানা পরিবর্তন করা হয় না এবং #FF এর রেফারেন্স ধরে রাখে (বা মূল myListপয়েন্টারটি বিরক্ত হয় না)।


সুত্র শব্দ (8) এবং (9) পদ্ধতি পরামিতি জন্য কোন গাদা বরাদ্দ থাকবে যার মানে জন্য রানটাইম কোডের প্রজন্ম লাফালাফি করার জন্য একটি কম্পাইলার নির্দেশ হয়। এটি #FF এ অবজেক্টটি পরিচালনা করতে আসল # 00 পয়েন্টার ব্যবহার করবে। যদি মূল পয়েন্টারটি আরম্ভ না করা হয় তবে রানটাইমটি থেমে যাবে যে অভিযোগটি আরম্ভ করা না হওয়ায় এটি এগিয়ে যেতে পারে না compla

আউট শব্দ একটি কম্পাইলার নির্দেশ যা প্রায় কাছাকাছি (9) এবং (10) এ সামান্য সংশোধন সহ সুত্র হিসাবে একই হয়। সংকলকটি আর্গুমেন্টটি অনির্বাচিত হওয়ার প্রত্যাশা করে এবং (8), (4) এবং (5) দিয়ে গাদাতে একটি অবজেক্ট তৈরি করতে এবং তার প্রারম্ভিক ঠিকানাটি আর্গুমেন্ট ভেরিয়েবলের মধ্যে সঞ্চয় করতে থাকবে। কোনও অনিচ্ছাকৃত ত্রুটি নিক্ষেপ করা হবে না এবং সংরক্ষণ করা পূর্ববর্তী কোনও রেফারেন্স হারিয়ে যাবে।


3

পাশাপাশি একটি বর্গ একটি ভিন্ন ক্ষেত্রটিকেই পুনঃস্থির অন্য কারো পরিবর্তনশীল আপনার অনুমতি হিসাবে, একাধিক মান আসতে ইত্যাদি ব্যবহার refবা outঅন্য কেউ জানে দেয় আপনি পরিবর্তনশীল তারা প্রদান না মনস্থ কি আপনি তাদের কাছ থেকে প্রয়োজন এবং কি

  • আপনি প্রয়োজন হবে না ref বা outআপনি কি সব করতে যাচ্ছেন পরিবর্তন জিনিষ হলে ভিতরেMyClass উদাহরণস্বরূপ যে যুক্তি পাস করা হয়েছে someClass

    • কলিং পদ্ধতি মত পরিবর্তন দেখতে হবে someClass.Message = "Hello World"কিনা আপনি ব্যবহার ref, outঅথবা কিছুই
    • someClass = new MyClass()ভিতরে myFunction(someClass)লিখতে লেখার আওতায় থাকা অবজেক্টটি আউট করে someClassনিয়ে যায়myFunction কেবল পদ্ধতির । কলিং পদ্ধতিটি MyClassএটি তৈরি করে এবং আপনার পদ্ধতিতে প্রেরণ করা প্রকৃত উদাহরণ সম্পর্কে এখনও জানে
  • আপনার দরকার ref বা outআপনি যদি someClassপুরো নতুন অবজেক্টের জন্য অদলবদল করার পরিকল্পনা করেন এবং কলিং পদ্ধতিটি আপনার পরিবর্তনটি দেখতে চান

    • someClass = new MyClass()ভিতরে লেখা লেখার মাধ্যমে myFunction(out someClass)দেখা যায় এমন বস্তুকে পরিবর্তন করেmyFunction

অন্যান্য প্রোগ্রামার বিদ্যমান

এবং তারা তাদের ডেটা দিয়ে আপনি কী করতে যাচ্ছেন তা জানতে চায়। কল্পনা করুন আপনি এমন একটি লাইব্রেরি লিখছেন যা লক্ষ লক্ষ বিকাশকারী ব্যবহার করবেন। আপনি যখন চান যে তারা যখন আপনার পদ্ধতিগুলি কল করে তখন আপনি তাদের ভেরিয়েবলগুলির সাথে কী করতে যাচ্ছেন তা জানতে চান

  • ব্যবহার ref "আপনি যখন আমার পদ্ধতিটি কল করবেন তখন কিছু মূল্যের জন্য নির্ধারিত একটি ভেরিয়েবলটি পাস করুন" এর একটি বিবৃতি দেয় aware সচেতন হোন যে আমি আমার পদ্ধতিটি চলাকালীন সম্পূর্ণরূপে অন্য কোনও কিছুর জন্য এটি পরিবর্তন করে দিতে পারি। আমার যখন শেষ হবে"

  • ব্যবহারটি outআমার পদ্ধতির সাথে একজন স্থানধারককে পরিবর্তনশীল হিসাবে একটি বক্তব্য তৈরি করে a এটির কোনও মূল্য আছে বা না তা বিবেচ্য নয়; সংকলক আমাকে এটিকে একটি নতুন মূল্যে নির্ধারিত করতে বাধ্য করবে I আমি একেবারে গ্যারান্টি দিচ্ছি যে বিষয়টি আপনার দ্বারা চিহ্নিত করেছে আপনি আমার পদ্ধতিটি বলার আগে পরিবর্তনশীল, আমার কাজ শেষ হওয়ার পরে আলাদা হবে

যাইহোক, সি # 7.2 এ একটি inসংশোধকও রয়েছে

এবং এটি পদ্ধতিটিকে অন্য কোনও উদাহরণ হিসাবে পাসের অদলবদল হতে বাধা দেয়। এটিকে লক্ষ লক্ষ বিকাশকারীদের বলার মতো মনে করুন "আমাকে আপনার মূল পরিবর্তনশীল রেফারেন্সটি পাস করুন এবং আমি প্রতিশ্রুতি দিয়েছি যে আপনার সাবধানে তৈরি করা ডেটা অন্য কোনও কিছুর জন্য সরিয়ে নেব না"। inকিছু অদ্ভুততা রয়েছে, এবং কিছু ক্ষেত্রে যেমন কোনও সংক্ষিপ্ত রূপান্তরটির প্রয়োজন হতে পারে আপনার সংক্ষিপ্তটির সাথে সামঞ্জস্য করার জন্যin int অস্থায়ীভাবে একটি ইনট তৈরি করবে, আপনার সংক্ষিপ্ত আকারটি আরও প্রশস্ত করবে, রেফারেন্স দিয়ে এটি পাস করবে এবং শেষ করবে। এটি এটি করতে পারে কারণ আপনি ঘোষণা করেছেন যে আপনি এটির সাথে ঝামেলা করছেন না।


মাইক্রোসফ্ট .TryParseসংখ্যার ধরণের পদ্ধতিগুলির মাধ্যমে এটি করেছে:

int i = 98234957;
bool success = int.TryParse("123", out i);

outতারা এখানে সক্রিয়ভাবে ঘোষণা করার সাথে সাথে প্যারামিটারটিকে পতাকাঙ্কিত করে "আমরা অবশ্যই আপনার ব্যয়করভাবে তৈরি কারুকৃত মান 98234957 এর বাইরে অন্য কোনও কিছুর জন্য পরিবর্তন করতে যাচ্ছি"

অবশ্যই, তাদের মানগুলি পার্সিংয়ের মতো জিনিসের জন্য করতে হবে কারণ যদি পার্স পদ্ধতিটি অন্য কোনও কিছুর জন্য মূল্য প্রকারটি বদলানোর অনুমতি না দেয় তবে এটি খুব ভালভাবে কাজ করে না .. তবে কল্পনা করুন যে কারওর মধ্যে কিছু কাল্পনিক পদ্ধতি ছিল আপনি তৈরি করছেন লাইব্রেরি:

public void PoorlyNamedMethod(out SomeClass x)

আপনি দেখতে পাচ্ছেন এটি একটি out, এবং আপনি এভাবে জানতে পারেন যে আপনি যদি সংখ্যার ক্রাঞ্চিংয়ের জন্য ঘন্টা ব্যয় করে নিখুঁত সোমক্লাস তৈরি করেন:

SomeClass x = SpendHoursMakingMeAPerfectSomeClass();
//now give it to the library
PoorlyNamedMethod(out x);

ভাল যে সময় নষ্ট ছিল, এই নিখুঁত বর্গ তৈরি করতে এই সমস্ত ঘন্টা সময় নেয়। এটি অবশ্যই দূরে ফেলে দেওয়া হবে এবং পুরলি নামমেথোদ দ্বারা প্রতিস্থাপিত হবে


3

সংক্ষিপ্ত উত্তর খুঁজছেন তাদের জন্য।

refএবং outকীওয়ার্ড উভয়ই পাস-বাই- ব্যবহার করতে ব্যবহৃত হয় reference


refকীওয়ার্ডের একটি ভেরিয়েবলের অবশ্যই একটি মান থাকতে হবে বা অবশ্যই কোনও অবজেক্টের কাছে বা তার পাসের null আগে উল্লেখ করতে হবে ।


ভিন্ন ref, এর একটি পরিবর্তনশীল outশব্দ একটি মান থাকতে হবে অথবা একটি বস্তু বা পড়ুন আবশ্যক null পর তার ক্ষণস্থায়ী একটি মান আছে বা একটি বস্তু পড়ুন করার কোন প্রয়োজন সেইসাথে সামনে ক্ষণস্থায়ী।


2

অনেক দুর্দান্ত ব্যাখ্যা ব্যাখ্যা করতে, আমি নিম্নলিখিত কনসোল অ্যাপ্লিকেশনটি বিকাশ করেছি:

using System;
using System.Collections.Generic;

namespace CSharpDemos
{
  class Program
  {
    static void Main(string[] args)
    {
      List<string> StringList = new List<string> { "Hello" };
      List<string> StringListRef = new List<string> { "Hallo" };

      AppendWorld(StringList);
      Console.WriteLine(StringList[0] + StringList[1]);

      HalloWelt(ref StringListRef);
      Console.WriteLine(StringListRef[0] + StringListRef[1]);

      CiaoMondo(out List<string> StringListOut);
      Console.WriteLine(StringListOut[0] + StringListOut[1]);
    }

    static void AppendWorld(List<string> LiStri)
    {
      LiStri.Add(" World!");
      LiStri = new List<string> { "¡Hola", " Mundo!" };
      Console.WriteLine(LiStri[0] + LiStri[1]);
    }

    static void HalloWelt(ref List<string> LiStriRef)
     { LiStriRef = new List<string> { LiStriRef[0], " Welt!" }; }

    static void CiaoMondo(out List<string> LiStriOut)
     { LiStriOut = new List<string> { "Ciao", " Mondo!" }; }
   }
}
/*Output:
¡Hola Mundo!
Hello World!
Hallo Welt!
Ciao Mondo!
*/
  • AppendWorld: StringListনামের একটি অনুলিপি LiStriপাস হয়েছে। পদ্ধতির শুরুতে, এই অনুলিপিটি মূল তালিকাটি উল্লেখ করে এবং তাই এই তালিকাটি সংশোধন করতে ব্যবহার করা যেতে পারে। পরে পদ্ধতির অভ্যন্তরে LiStriঅন্য কোনও List<string>অবজেক্টের উল্লেখ করে যা মূল তালিকাকে প্রভাবিত করে না।

  • HalloWelt: LiStriRefইতিমধ্যে সক্রিয়া একজন ওরফে হয় ListStringRef। পাস করা List<string>অবজেক্টটি একটি নতুন সূচনা করার জন্য ব্যবহৃত হয়, সুতরাং refএটি প্রয়োজনীয় ছিল।

  • CiaoMondo: LiStriOutএর একটি নাম ListStringOutএবং এটি আরম্ভ করা আবশ্যক।

সুতরাং, যদি কোনও পদ্ধতি কেবল উত্তীর্ণ ভেরিয়েবল দ্বারা রেফারেন্স করা অবজেক্টটি সংশোধন করে, সংকলক আপনাকে ব্যবহার করতে দেয় না এবং আপনাকে ব্যবহার করা outউচিত নয় refকারণ এটি সংকলক নয় বরং কোডের পাঠককে বিভ্রান্ত করবে। যদি পদ্ধতিটি পাস হওয়া আর্গুমেন্টটিকে অন্য কোনও বস্তুর রেফারেন্স তৈরি করে, refইতিমধ্যে প্রারম্ভিক অবজেক্টের outজন্য এবং এমন পদ্ধতির জন্য ব্যবহার করুন যা পাস হওয়া আর্গুমেন্টের জন্য একটি নতুন অবজেক্টকে আরম্ভ করতে হবে। পাশাপাশি, refএবং outএকই আচরণ।


1

এগুলি বেশ একইরকম - পার্থক্যটি হ'ল আপনি আউট প্যারামিটার হিসাবে যে ভেরিয়েবলটি পাস করেন তা আরম্ভ করার প্রয়োজন হয় না এবং রেফ প্যারামিটার ব্যবহারের পদ্ধতিটি এটিকে কিছুতে সেট করতে হয়।

int x;    Foo(out x); // OK 
int y;    Foo(ref y); // Error

রেফ প্যারামিটারগুলি এমন ডেটার জন্য যা পরিবর্তিত হতে পারে, আউট প্যারামিটারগুলি এমন ডেটার জন্য যা ফাংশনের জন্য অতিরিক্ত আউটপুট (যেমন int.TryParse) যা ইতিমধ্যে কোনও কিছুর জন্য রিটার্ন মান ব্যবহার করে।


1

নীচে আমি রেফ এবং আউট উভয় ব্যবহার করে একটি উদাহরণ দেখিয়েছি । এখন, আপনারা সবাই রেফ এবং আউট সম্পর্কে সাফ হয়ে যাবেন।

নীচে উল্লিখিত উদাহরণে যখন আমি মন্তব্য করি // myRefObj = নতুন মাই ক্লাস {নাম = "রেফ বাইরে বলা হয়!"}; লাইনটি, "নিযুক্ত স্বাক্ষরিত স্থানীয় ভেরিয়েবল" মাইআরএফওবিজে "ব্যবহার করে একটি ত্রুটি পাবে , তবে এর বাইরে কোনও ত্রুটি নেই ।

রেফ কোথায় ব্যবহার করবেন : যখন আমরা একটি প্যারামিটার দিয়ে একটি প্রক্রিয়া কল করি এবং একই প্যারামিটারটি সেই প্রোচের আউটপুট সংরক্ষণ করতে ব্যবহৃত হবে।

কোথায় আউট আউট ব্যবহার করবেন: যখন আমরা প্যারামিটারে নন একটি পদ্ধতি কল করি এবং সেই একই পরম সেই প্রকট থেকে মানটি ফেরত দিতে ব্যবহৃত হবে। আউটপুট নোট করুন

public partial class refAndOutUse : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        myClass myRefObj;
        myRefObj = new myClass { Name = "ref outside called!!  <br/>" };
        myRefFunction(ref myRefObj);
        Response.Write(myRefObj.Name); //ref inside function

        myClass myOutObj;
        myOutFunction(out myOutObj);
        Response.Write(myOutObj.Name); //out inside function
    }

    void myRefFunction(ref myClass refObj)
    {
        refObj.Name = "ref inside function <br/>";
        Response.Write(refObj.Name); //ref inside function
    }
    void myOutFunction(out myClass outObj)
    {
        outObj = new myClass { Name = "out inside function <br/>" }; 
        Response.Write(outObj.Name); //out inside function
    }
}

public class myClass
{
    public string Name { get; set; }
} 

1
 public static void Main(string[] args)
    {
        //int a=10;
        //change(ref a);
        //Console.WriteLine(a);
        // Console.Read();

        int b;
        change2(out b);
        Console.WriteLine(b);
        Console.Read();
    }
    // static void change(ref int a)
    //{
    //    a = 20;
    //}

     static void change2(out int b)
     {
         b = 20;
     }

আপনি এই কোডটি চেক করতে পারেন এটি যখন আপনি "রেফ" ব্যবহার করেন তখন এর সম্পূর্ণ পার্থক্য বর্ণনা করে আপনি এর ইতিমধ্যে / স্ট্রিংটি আরম্ভ করেছেন

তবে আপনি যখন "আউট" ব্যবহার করেন এটি উভয় অবস্থাতেই কাজ করে আপনি যে ইনটি / স্ট্রিংটি আরম্ভ করেন বা না তবে আপনাকে অবশ্যই সেই ক্রিয়াকলাপটি / স্ট্রিংটি আরম্ভ করতে হবে


1

রেফ: রেফার্স কীওয়ার্ডটি একটি রেফারেন্স হিসাবে আর্গুমেন্ট পাস করতে ব্যবহৃত হয়। এর অর্থ হ'ল যখন সেই প্যারামিটারটির মানটি পদ্ধতিতে পরিবর্তন করা হয়, এটি কলিং পদ্ধতিতে প্রতিফলিত হয়। একটি রেফার কীওয়ার্ড ব্যবহার করে পাস করা একটি আর্গুমেন্টটি কল পদ্ধতিতে পাস করার আগে কলিং পদ্ধতিতে শুরু করা উচিত ized

আউট: আউট কীওয়ার্ডটি রেফ কীওয়ার্ডের মতো একটি আর্গুমেন্ট পাস করার জন্যও ব্যবহৃত হয়, তবে যুক্তিটি কোনও মান নির্ধারণ না করেই পাস করা যেতে পারে। আউট কীওয়ার্ড ব্যবহার করে পাস করা একটি আর্গুমেন্ট কলিং পদ্ধতিতে ফিরে আসার আগে তাকে বলা পদ্ধতিতে শুরু করা উচিত must

public class Example
{
 public static void Main() 
 {
 int val1 = 0; //must be initialized 
 int val2; //optional

 Example1(ref val1);
 Console.WriteLine(val1); 

 Example2(out val2);
 Console.WriteLine(val2); 
 }

 static void Example1(ref int value) 
 {
 value = 1;
 }
 static void Example2(out int value) 
 {
 value = 2; 
 }
}

/* Output     1     2     

পদ্ধতি ওভারলোডিংয়ে রেফ এবং আউট

রেফ এবং আউট উভয়ই একই সাথে পদ্ধতি ওভারলোডিংয়ে ব্যবহার করা যায় না। তবে রান-টাইমে রেফ এবং আউটকে আলাদাভাবে চিকিত্সা করা হয় তবে সংকলনের সময় এগুলি একই আচরণ করা হয় (সিএলআর যখন রেফ এবং আউট জন্য আইএল তৈরি করেছিল তখন দুটির মধ্যে পার্থক্য হয় না)।


0

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

কলারের দৃষ্টিকোণ থেকে, সি # অনেক ক্ষেত্রে outপ্যারামিটারের সাথে কোনও পদ্ধতি কল করার পরে অনুমান করা হবে যে প্রথমে পড়া না করে পাসের ভেরিয়েবলটি লেখা হবে। অন্যান্য ভাষায় লিখিত পদ্ধতিগুলিকে কল করার সময় এই ধারণাটি সঠিক নাও হতে পারে। উদাহরণ স্বরূপ:

struct MyStruct
{
   ...
   myStruct(IDictionary<int, MyStruct> d)
   {
     d.TryGetValue(23, out this);
   }
}

যদি অ্যাসাইনমেন্টের মতো দেখায়ও সি # ব্যতীত অন্য কোনও ভাষায় রচিত myDictionaryএকটি IDictionary<TKey,TValue>বাস্তবায়ন সনাক্ত করে তবে MyStruct s = new MyStruct(myDictionary);এটি সম্ভবত sসংশোধিত ছাড়তে পারে ।

দ্রষ্টব্য যে VB.NET- এ লিখিত নির্মাতারা, সি # র মতো নয়, তথাকথিত পদ্ধতিগুলি কোনও outপরামিতিগুলিকে সংশোধন করবে এবং শর্ত ছাড়িয়ে সমস্ত ক্ষেত্র সাফ করবে কিনা তা নিয়ে কোনও অনুমান করা যায় না । উপরে বর্ণিত অদ্ভুত আচরণটি সম্পূর্ণরূপে ভিবিতে বা সম্পূর্ণ সি # তে লিখিত কোডের সাথে ঘটে না, তবে সি # তে লিখিত কোডটি ভিবি.এনইটি-তে লিখিত পদ্ধতিতে কল করলে তা ঘটতে পারে।


0

আপনি যদি আপনার প্যারামিটারটিকে রেফ হিসাবে পাস করতে চান তবে ফাংশনটিতে প্যারামিটারটি পাস করার আগে আপনি এটি শুরু করতে হবে অন্যথায় সংকলক নিজেই ত্রুটিটি দেখায় B তবে পরামিতি আউট করার ক্ষেত্রে আপনাকে অবজেক্টের প্যারামিটারটি পাস করার আগে আরম্ভ করার দরকার নেই the মেথড.আপনি কলিং পদ্ধতিতে নিজেই সূচনা করতে পারেন।


-3

মনে রাখবেন যে ফাংশনের অভ্যন্তরে রেফারেন্স প্যারামিটারটি সরাসরি কাজ করা হয়।

উদাহরণ স্বরূপ,

    public class MyClass
    {
        public string Name { get; set; }
    }

    public void Foo()
    {
        MyClass myObject = new MyClass();
        myObject.Name = "Dog";
        Bar(myObject);
        Console.WriteLine(myObject.Name); // Writes "Dog".
    }

    public void Bar(MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

এটি ক্যাট নয়, কুকুর লিখবে। অতএব আপনার সরাসরি কোনও অবজেক্টে কাজ করা উচিত।


6
যদিও এখানে সমস্ত কিছু সত্যই সত্য তবে এটি রেফারেন্স বা আউট দ্বারা মূল্য দ্বারা পার্থক্যটি ব্যাখ্যা করে না। সর্বোপরি এটি অর্ধেক রেফারেন্স এবং মান / অপরিবর্তনীয় প্রকারের মধ্যে পার্থক্য ব্যাখ্যা করে।
কনরাড ফ্রিক্স

আপনি যদি কোডটি বিড়ালকে লিখতে চান তবে দয়া করে 'রেফ' কী এর সাথে সেই বস্তুটি পাস করুন: পাবলিক স্ট্যাটিক শূন্য বার (রেফ মাই ক্লাস সামোজ অবজেক্ট), বার (রেফ মাইওজেক্ট);
ড্যানিয়েল বোটেরো কোরিয়া

-4

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

        string a = "Hello";

        string b = "goodbye";

        b = a; //attempt to make b point to a, won't work.

        a = "testing";

        Console.WriteLine(b); //this will produce "hello", NOT "testing"!!!!

এ কারণেই যদি আপনার পরিবর্তনের প্রয়োজন হয় তবে যদি পরিবর্তনগুলি সেগুলি তৈরির সুযোগের বাইরে উপস্থিত থাকতে চান, আপনি অন্যথায় কোনও রেফারেন্স দিচ্ছেন না।

আমি যতটা অবগত আছি আপনি কেবল স্ট্রাইক / মান ধরণের এবং স্ট্রিংয়ের জন্যই রেফ প্রয়োজন, কারণ স্ট্রিং একটি রেফারেন্স টাইপ যা ভান করে তবে এটি মান ধরণের নয়।

আমি এখানে সম্পূর্ণ ভুল হতে পারি, যদিও আমি নতুন am


5
অ্যাডউইন স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম। স্ট্রিংগুলি রেফারেন্স দ্বারা পাস করা হয়েছে ঠিক যেমনটি আমি জানি অন্য যে কোনও অবজেক্টের মতো। আপনি বিভ্রান্ত হতে পারেন কারণ স্ট্রিংগুলি অপরিবর্তনীয় বস্তু, তাই এটি রেফারেন্সের দ্বারা পাস হয়েছে এমনটি স্পষ্ট নয়। কল্পনা করুন যে স্ট্রিংয়ের একটি পদ্ধতি Capitalize()রয়েছে যা স্ট্রিংয়ের বিষয়বস্তুকে মূলধনীতে পরিবর্তন করে। তারপর আপনি আপনার লাইন প্রতিস্থাপন তাহলে a = "testing";সঙ্গে a.Capitalize();, তারপর আপনার আউটপুট "হ্যালো", না "হ্যালো" হবে। অপরিবর্তনীয় প্রকারের একটি সুবিধা হ'ল আপনি রেফারেন্সগুলি প্রায় পাশ করতে পারেন এবং মান পরিবর্তন করে অন্যান্য কোড সম্পর্কে চিন্তা করবেন না।
ডন কার্কবি

2
একধরণের তিনটি মৌলিক ধরণের শব্দার্থক শব্দ প্রকাশ করতে পারে: পার্সোনাল রেফারেন্স শব্দার্থক শব্দ, পরিবর্তনীয় মান শব্দার্থক এবং অপরিবর্তনীয় শব্দার্থক। টি এবং টি জাতীয় টাইপের ভেরিয়েবলগুলি বিবেচনা করুন, যার ক্ষেত্র বা সম্পত্তি মি আছে, এবং ধরে নিন যে x এর সাথে অনুলিপিযুক্ত। যদি টি এর রেফারেন্স শব্দার্থবিদ্যা থাকে, তবে xm এ পরিবর্তনগুলি ym দ্বারা পর্যবেক্ষণ করা হবে যদি টি এর মান শব্দার্থক থাকে, তবে টি এম এর প্রভাব ছাড়াই xm পরিবর্তন করতে পারে যদি টিতে অবিচ্ছেদ্য শব্দার্থ থাকে, তবে xm বা ym কখনও পরিবর্তন হবে না। অপরিবর্তনীয় শব্দার্থবিজ্ঞান রেফারেন্স বা মান বস্তু দ্বারা সিমুলেট করা যায়। স্ট্রিংগুলি পরিবর্তনযোগ্য রেফারেন্স অবজেক্ট।
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.