আমি কীভাবে গাইডের একটি পরামিতি ডিফল্ট করতে পারি? সি # তে এমপিটি?


178

আমি বলতে চাই:

public void Problem(Guid optional = Guid.Empty)
{
}

তবে সংকলকটি অভিযোগ করে যে গাইড E এম্পটি কোনও সংকলনের সময় ধ্রুবক নয়।

আমি যে API টি ব্যবহার করতে পারি তা পরিবর্তন করতে চাই না:

 Nullable<Guid>


Nullable<Guid> optional = null(বা আরও ক্ষুদ্রতর, Guid? optional = null) এ স্যুইচ করার ক্ষেত্রে কী ভুল ? বর্তমানে এতে পাস করা কোনও গাইডই কোনও কোড পরিবর্তন ছাড়াই প্রয়োজনীয় করে তোলে।
এনএইচ।

উত্তর:


235

সমাধান

new Guid()পরিবর্তে আপনি ব্যবহার করতে পারেন

public void Problem(Guid optional = new Guid())
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

আপনি ব্যবহার করতে পারেন default(Guid)

default(Guid) এছাড়াও ঠিক হিসাবে কাজ করবে new Guid()

কারণ গাইড একটি মান প্রকার নয় রেফারেন্স টাইপ, সুতরাং, এর default(Guid)সমান নয়null উদাহরণস্বরূপ, পরিবর্তে, এটি ডিফল্ট কন্সট্রাকটর আহ্বান সমান নয়।

যার অর্থ এই:

public void Problem(Guid optional = default(Guid))
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

এটি হুবহু মূল উদাহরণের মতো।

ব্যাখ্যা

কেন Guid.Emptyকাজ হয়নি ?

আপনি ত্রুটিটি পাওয়ার কারণটি কারণ Emptyহিসাবে সংজ্ঞায়িত হয়েছে:

public static readonly Guid Empty;

সুতরাং, এটি একটি পরিবর্তনশীল, ধ্রুবক নয় (হিসাবে হিসাবে সংজ্ঞায়িত করা হয় static readonlyনা const)। সংকলকটিতে কেবল প্যারামিটারের ডিফল্ট মানগুলি (কেবল রানটাইম-কেবল পরিচিত নয়) হিসাবে সংকলক-জ্ঞাত মান থাকতে পারে।

মূল কারণ যে আপনি একটি থাকতে পারে না হয় constকোনোstruct , enumউদাহরণস্বরূপ পৃথক। আপনি যদি এটি চেষ্টা করেন তবে এটি সংকলন করবে না।

আর একবার কারণটি হ'ল এটি structকোনও আদিম ধরণের নয়।
.NET- এ সমস্ত আদিম ধরণের তালিকার জন্য দেখুন http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(নোট যেটি enumসাধারণতint , যা একটি আদিম)

কিন্তু new Guid() খুব ধ্রুবকও নয়!

আমি বলছি না যে এটি একটি ধ্রুবক প্রয়োজন। এটি এমন কিছু প্রয়োজন যা সংকলন সময়ে সিদ্ধান্ত নেওয়া যেতে পারে।Emptyএকটি ক্ষেত্র, সুতরাং, এটির সংকলন সময়ে (শুধুমাত্র রান সময়ের খুব শুরুর দিকে) এর মূল্য জানা যায় না।

ডিফল্ট প্যারামিটার মান অবশ্যই সংকলন সময়ে জানা থাকতে হবে, যা একটি constমান হতে পারে বা একটি সি # বৈশিষ্ট্য ব্যবহার করে সংজ্ঞায়িত এমন কিছু যা সংকলন সময়ে মূল্যকে জ্ঞাত করে তোলে, যেমন default(Guid)বা new Guid()(যা সংকলনের সময় সিদ্ধান্ত নেওয়া হয় structযেহেতু আপনি structনির্মাণকারীকে সংশোধন করতে পারবেন না) কোড)।

আপনি যখন সরবরাহ করতে defaultবা newসহজেই সরবরাহ করতে পারেন তবে আপনি একটি সরবরাহ করতে পারবেন না const(কারণ এটি আদিম ধরণের বা enumউপরে বর্ণিত হিসাবে নয়)। সুতরাং, আবারও বলছেন না যে alচ্ছিক প্যারামিটারের একটি ধ্রুবক, তবে সংকলক জ্ঞাত মান প্রয়োজন।


5
ঠিক আছে, এটির জন্য একটি সাধারণ ধ্রুবক প্রকাশের প্রয়োজন নেই - new Guid()উদাহরণস্বরূপ একটি ধ্রুবক প্রকাশ নয়। সি # স্পেসটি সম্পূর্ণ স্পষ্টভাবে সংজ্ঞায়িত করে যা কী অনুমোদিত তা কেবল ধ্রুবক সহ সীমাবদ্ধ নয়। (জাস্ট স্পষ্ট করা, এটা কার্যকরভাবে হয় একটি কম্পাইল সময় ধ্রুবক, শুধু একটি "ধ্রুবক অভিব্যক্তি" C # এর বৈশিষ্ট পদ)।
জন স্কিটি

3
আমার উত্তরে অংশটি ব্যাখ্যা পড়ুন । এই অংশের উত্তর যোগ করা।
মেলিগি

সুন্দর ব্যাখ্যা। ধন্যবাদ!
ড্যারিল

আপনি defaultআজকাল কেবলমাত্র :) ব্যবহার করতে পারেন :)
জোশিত

151

Guid.Emptyসমান new Guid(), যা সমান default(Guid)। সুতরাং আপনি ব্যবহার করতে পারেন:

public void Problem(Guid optional = default(Guid))

অথবা

public void Problem(Guid optional = new Guid())

মনে রাখবেন যে new Foo()মানটি তখনই প্রযোজ্য যখন:

  • আপনি সত্যই প্যারামিটারলেস কল করছেন কনস্ট্রাক্টরকে
  • Foo একটি মান ধরণ

অন্য কথায়, যখন সংকলকটি জানে এটি প্রকারের জন্য এটি কেবলমাত্র ডিফল্ট মান :)

(মজার বিষয় হল, আমি 99.9% নিশ্চিত যে এটি আপনার তৈরি কাস্টম কনস্ট্রাক্টরকে কল করবে নাnew Foo() C আপনি সি # তে মান ধরণের এমন কনস্ট্রাক্টর তৈরি করতে পারবেন না, তবে আপনি পারেন এটি আইএল ))

আপনি যে কোনও ধরণের default(Foo)বিকল্প ব্যবহার করতে পারেন ।


এখন কেন কম্পাইলার ত্রুটি বার্তা এটি আমাকে জানায় না, সংযোজকটি গাইড.এম্পটির কেসটি পরীক্ষা করে আরও একটি সহায়ক বার্তা দিতে পারে।
আয়ান রিংরোজ

4
@ আইয়ান রিংরোজ: আমি মনে করি না যে সংক্ষেপকারীর কাছে সাধারণভাবে টাইপ-নির্দিষ্ট বার্তা থাকা উচিত, সত্য বলতে হবে be
জন স্কিটি

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

1
এই একই জিনিসটি এএসপি.নেট এমভিসি নিয়ন্ত্রণকারী ক্রিয়ায় কাজ করবে না এমন কারণ কী হতে পারে? অন্যান্য সমস্ত alচ্ছিক প্যারামিটারগুলি কাজ করে (ইনট, স্ট্রিং) তবে এটি জিইউডির পক্ষে কাজ করে না, বলে "" / 'অ্যাপ্লিকেশনটিতে সার্ভার ত্রুটি The '.. "কোডটি উভয় স্পেসিফিকেশন (ডিফল্ট (গাইড) এবং নতুন গাইড ()) দিয়ে সূক্ষ্ম সংকলন করে তবে এই ত্রুটিটি জারি করে।
মেরে

@ ম্যারে: আমি জানি না, আমি ভয় পাই। আরেকটি বিকল্প Nullable<Guid>হ'ল সম্ভাব্যভাবে ব্যবহার করা ।
জন স্কিটি

18

আপনি কি ব্যবহার করতে পারবেন না:

default ( Guid ) ?


1
নং Operator '??' cannot be applied to operands of type 'System.Guid' and 'System.Guid'
পুনরাবৃত্তি

4
দুঃখিত, আমি বোঝাতে চাইনি ?? অপারেটর হিসাবে তবে জোর দেওয়া প্রশ্ন চিহ্ন হিসাবে - আমি সম্পাদনা করব!
নিক

9

গৃহীত উত্তরটি এএসপি.নেট এমভিসিতে কাজ করে না এবং এই রানটাইম ত্রুটির কারণ ঘটায়:

[ArgumentException: The parameters dictionary contains a null entry for parameter 'optional' of non-nullable type 'System.Guid' for method 'System.Web.Mvc.ActionResult Problem(System.Guid)' ....

পরিবর্তে, আপনি নিম্নলিখিত করতে পারেন:

public void Problem(Guid? optional)
{
    if (optional == null)
    {
        optional = new Guid();
    }
}

ডাউন-ভোটিংয়ের কারণটি আমি দেখছি: প্রশ্নটি নির্দিষ্ট করে যে নুলযোগ্য <গুড> ব্যবহার করার জন্য এপিআই পরিবর্তন করা যাবে না - যথেষ্ট পরিমাণে
মজিক্স

আপনি খালি গাইড মান সহ স্পষ্টভাবে প্যারামিটারটিকে "alচ্ছিক" বরাদ্দ করতে না চাইলে আমি মনে করি এটি গাইডের optionচ্ছিক প্যারামিটার সংজ্ঞায়নের জন্য সবচেয়ে প্রাকৃতিক উপায়।
গনজালো ম্যান্ডেজ 21

4

সংকলকটি বেশ সঠিক; Guid.Emptyএকটি সংকলন-সময় ধ্রুবক নয়। আপনি এইভাবে একটি পদ্ধতি ওভারলোড তৈরীর চেষ্টা করতে পারেন:

public void Problem()
{
    Problem(Guid.Empty);
}

আমি বলেছিলাম যে আমি এপিআই পরিবর্তন করতে চাই না, যে পদ্ধতিতে আমি চেষ্টা করতে চাইছি তার ওভারের 10 পারম রয়েছে!
ইয়ান রিংরোজ

@ আইয়ান রিংরোজ, যদিও আমি Guid x = default(Guid)সমাধান হিসাবে একমত, তবে মনে রাখবেন যে অন্য ফাংশন ওভারলোড যুক্ত করা কোনও alচ্ছিক যুক্তি যুক্ত করার চেয়ে আরও জটিল করে তোলে না। এটি reallyচ্ছিক যুক্তি যেভাবেই করে।
টেনফোর

@ ততক্ষণে, 10 টি alচ্ছিক পারম হিসাবে একই কাজ করতে অনেকগুলি নতুন ফাংশন ওভারলোড হতে হবে!
ইয়ান রিংরোজ

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

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