কীভাবে একটি একক বস্তু [] কে প্যারাম অবজেক্টে পাস করতে হবে []


124

আমার একটি পদ্ধতি রয়েছে যা প্যারামস অবজেক্ট নেয় [যেমন:

void Foo(params object[] items)
{
    Console.WriteLine(items[0]);
}

আমি যখন এই পদ্ধতিতে দুটি অবজেক্ট অ্যারে পাস করি তখন এটি দুর্দান্ত কাজ করে:

Foo(new object[]{ (object)"1", (object)"2" }, new object[]{ (object)"3", (object)"4" } );
// Output: System.Object[]

তবে যখন আমি কোনও একক বস্তু পাস করি [], তখন এটি আমার বস্তুটিকে [] প্রথম প্যারাম হিসাবে গ্রহণ করে না, পরিবর্তে এটি এর সমস্ত উপাদানকে গ্রহণ করে যেমন আমি তাদের একের পর এক পাস করতে চেয়েছিলাম:

Foo(new object[]{ (object)"1", (object)"2" });
// Output: 1, expected: System.Object[]

প্যারাম অ্যারেতে প্রথম যুক্তি হিসাবে আমি কীভাবে একটি একক বস্তু [] পাস করব?

উত্তর:


99

একটি সাধারণ টাইপকাস্ট নিশ্চিত করবে যে সংকলক জানে এই ক্ষেত্রে আপনার অর্থ কি।

Foo((object)new object[]{ (object)"1", (object)"2" }));

যেহেতু একটি অ্যারে অবজেক্টের উপপ্রকার, এটি সমস্ত কার্যকর হয়। একটি বিজোড় সমাধান বিট যদিও, আমি সম্মত।


2
প্যারামগুলি যেভাবে কাজ করে তা অপ্রয়োজনীয় বলে মনে হয়, এবং সাব-ক্লিপ সি # ডিজাইন, যা আমরা অন্যান্য ভাষায় অভ্যস্ত হয়েছি given প্যারামগুলি কেবল একটি ফর্ম গ্রহণ করার জন্য তৈরি করা যেতে পারে এবং এই জাতীয় স্প্রেস যুক্ত বৈশিষ্ট্য যুক্ত করা যেতে পারে যা কেবলমাত্র এই ক্ষেত্রে নয়, পুরো ভাষার উপকারে আসবে। উদাহরণস্বরূপ, আমরা সমস্ত প্যারাম কলগুলিকে Foo (ওজেক্ট [0], আপত্তি [1]) হতে বাধ্য করতে পারি এবং তারপরে একটি পৃথক স্প্রেড অপারেটরকে Foo (... অবজেক্ট) এর অনুমতি দেয়।
হিটনিল্যান্ড

1
বুঝতে পেরেছিলাম যে আমি স্পষ্ট করেছিলাম না যে আমি এন্ডার্স হিজলসবার্গের প্রতি আমার শ্রদ্ধা, তিনি বিশ্বের অন্যতম সেরা ভাষা ডিজাইনার। তবে আমরা কারও কারও কাজের উন্নতি সম্পর্কে যথেষ্ট চিন্তাভাবনা করতে পারি, তাই প্রযুক্তিটি।
হাইটনিল্যান্ড

74

paramsপরামিতি পরিবর্তক কলারের একটি পদ্ধতি একাধিক আর্গুমেন্ট ক্ষণস্থায়ী জন্য একটি শর্টকাট সিনট্যাক্স দেয়। paramsপ্যারামিটার সহ একটি পদ্ধতি কল করার দুটি উপায় রয়েছে :

1) প্যারামিটার ধরণের একটি অ্যারের সাথে কল করা, সেক্ষেত্রে paramsকীওয়ার্ডটির কোনও প্রভাব নেই এবং অ্যারেটি সরাসরি পদ্ধতিতে দেওয়া হয়:

object[] array = new[] { "1", "2" };

// Foo receives the 'array' argument directly.
Foo( array );

2) অথবা, যুক্তিগুলির একটি বর্ধিত তালিকা সহ কল ​​করা, সেক্ষেত্রে সংকলক স্বয়ংক্রিয়ভাবে একটি অস্থায়ী অ্যারেতে আর্গুমেন্টের তালিকাটি গুটিয়ে ফেলবে এবং এটি পদ্ধতিতে প্রেরণ করবে:

// Foo receives a temporary array containing the list of arguments.
Foo( "1", "2" );

// This is equivalent to:
object[] temp = new[] { "1", "2" );
Foo( temp );


" params object[]" পরামিতি সহ কোনও পদ্ধতিতে অবজেক্ট অ্যারেতে যাওয়ার জন্য , আপনি হয় করতে পারেন:

1) ম্যানুয়ালি একটি মোড়কের অ্যারে তৈরি করুন এবং লাসসেভক দ্বারা উল্লিখিত হিসাবে এটি সরাসরি পদ্ধতিতে পাস করুন :

Foo( new object[] { array } );  // Equivalent to calling convention 1.

2) বা, অ্যাডামobject দ্বারা উল্লিখিত হিসাবে যুক্তিটি নিক্ষেপ করুন , সেক্ষেত্রে সংকলক আপনার জন্য মোড়কের অ্যারে তৈরি করবে:

Foo( (object)array );  // Equivalent to calling convention 2.


তবে, যদি পদ্ধতির লক্ষ্যটি একাধিক অবজেক্ট অ্যারে প্রসেস করা হয় তবে এটি স্পষ্টত params object[][]পরামিতি দ্বারা ঘোষণা করা আরও সহজ হতে পারে । এটি আপনাকে আর্গুমেন্ট হিসাবে একাধিক অ্যারে পাস করার অনুমতি দেবে:

void Foo( params object[][] arrays ) {
  foreach( object[] array in arrays ) {
    // process array
  }
}

...
Foo( new[] { "1", "2" }, new[] { "3", "4" } );

// Equivalent to:
object[][] arrays = new[] {
  new[] { "1", "2" },
  new[] { "3", "4" }
};
Foo( arrays );

সম্পাদনা করুন: রেমন্ড চেন এই আচরণ এবং এটি একটি নতুন পোস্টে সি # নির্দিষ্টকরণের সাথে কীভাবে সম্পর্কিত তা বর্ণনা করে ।


8

এটি লিনকুতে জড়িত একটি লাইন সমাধান।

var elements = new String[] { "1", "2", "3" };
Foo(elements.Cast<object>().ToArray())


2

এই সমস্যাটি সমাধানের আর একটি উপায় (এটি এত ভাল অনুশীলন নয় তবে সৌন্দর্য দেখায়):

static class Helper
{
    public static object AsSingleParam(this object[] arg)
    {
       return (object)arg;
    }
}

ব্যবহার:

f(new object[] { 1, 2, 3 }.AsSingleParam());

1

একটি বিকল্প হ'ল আপনি এটিকে অন্য অ্যারেতে গুটিয়ে রাখতে পারেন:

Foo(new object[]{ new object[]{ (object)"1", (object)"2" } });

কুৎসিত ধরনের, তবে যেহেতু প্রতিটি আইটেম একটি অ্যারে, আপনি সমস্যাটি দূরে সরিয়ে দেওয়ার জন্য কেবল এটি ফেলে দিতে পারবেন না ... যেমন যদি এটি ফু (প্যারাম অবজেক্ট আইটেম) থাকে তবে আপনি কেবল এটি করতে পারেন:

Foo((object) new object[]{ (object)"1", (object)"2" });

বিকল্পভাবে, আপনি ফু এর আর একটি ওভারলোড হওয়া উদাহরণ সংজ্ঞায়নের চেষ্টা করতে পারেন যা কেবল একটি একক অ্যারে লাগে:

void Foo(object[] item)
{
    // Somehow don't duplicate Foo(object[]) and
    // Foo(params object[]) without making an infinite
    // recursive call... maybe something like
    // FooImpl(params object[] items) and then this
    // could invoke it via:
    // FooImpl(new object[] { item });
}

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