ফার্স্টআরডিফল্ট: নাল ব্যতীত ডিফল্ট মান


142

আমি এটা বুঝতে হিসাবে, Linq পদ্ধতি FirstOrDefault()একটি আসতে পারেন Defaultনাল ছাড়া অন্য কিছুর মান। আমি যে কাজটি করিনি তা হ'ল কোয়েরির ফলাফলের কোনও আইটেম না থাকলে নাল ব্যতীত কী ধরণের জিনিস এই (এবং অনুরূপ) পদ্ধতি দ্বারা ফিরে আসতে পারে। এটি কি এমন কোনও নির্দিষ্ট উপায়ে সেট আপ করা যেতে পারে যাতে কোনও নির্দিষ্ট প্রশ্নের জন্য কোনও মান না থাকলে কিছু পূর্বনির্ধারিত মান ডিফল্ট মান হিসাবে ফিরে আসে?


147
পরিবর্তে YourCollection.FirstOrDefault(), আপনি YourCollection.DefaultIfEmpty(YourDefault).First()উদাহরণস্বরূপ ব্যবহার করতে পারেন ।
অলস

6
আমি বেশ কিছুক্ষণ ধরে উপরের মন্তব্যের মতো কিছু সন্ধান করছি, এটি প্রচুর পরিমাণে সহায়তা করেছিল। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
ব্র্যান্ডন 16

উপরের মন্তব্যটি সেরা উত্তর।
টম প্যাডিলা

আমার ক্ষেত্রে @ স্লো উত্তরটি কার্যকর হয় নি যখন প্রত্যাশিত মানটি হ্রাসযোগ্য হয় এবং অযোগ্য হয়। আমি তার MyCollection.Last().GetValueOrDefault(0)জন্য ব্যবহার করেছি অন্যথায় নীচে @ জন স্কিটির উত্তর আইএমও সঠিক।
জুনিয়র

উত্তর:


46

সাধারণ ক্ষেত্রে, কেবল মান ধরণের জন্য নয়:

static class ExtensionsThatWillAppearOnEverything
{
    public static T IfDefaultGiveMe<T>(this T value, T alternate)
    {
        if (value.Equals(default(T))) return alternate;
        return value;
    }
}

var result = query.FirstOrDefault().IfDefaultGiveMe(otherDefaultValue);

আবার এটি আপনার ক্রমটিতে কিছু ছিল কিনা তা প্রথম থেকেই বলতে পারে না বা প্রথম মানটি যদি ডিফল্ট ছিল।

আপনি যদি এই সম্পর্কে যত্নশীল হন তবে আপনি এমন কিছু করতে পারেন

static class ExtensionsThatWillAppearOnIEnumerables
{
    public static T FirstOr<T>(this IEnumerable<T> source, T alternate)
    {
        foreach(T t in source)
            return t;
        return alternate;
    }
}

এবং হিসাবে ব্যবহার করুন

var result = query.FirstOr(otherDefaultValue);

যদিও মিঃ স্টেক দেখিয়েছেন এটি ঠিক তেমনি করা সম্ভব .DefaultIfEmpty(...).First()


আপনার জেনেরিক পদ্ধতিগুলি <T>তাদের নামে প্রয়োজন , তবে আরও গুরুতর এটি কার্যকর value == default(T)হয় না (কারণ Tসমতার জন্য তুলনা করা যায় কিনা কে জানে ?)
আকাশম

এটি নির্দেশ করার জন্য ধন্যবাদ, @ আকাশম; আমি এখন এটি চেষ্টা করেছি এবং আমার মনে হয় এটি ঠিক হওয়া উচিত (যদিও আমি মান ধরণের জন্য বক্সিং পছন্দ করি না)।
19:55

3
EqualityComparer<T>.Default.Equals(value, default(T))null
@ রোলিং

199

আমি এটি বুঝতে পেরেছি যে, লিংকে পদ্ধতিতে ফার্স্টঅরডেফল্ট () নাল ব্যতীত অন্য কোনও কিছুর ডিফল্ট মান দিতে পারে।

না, বরং, এটি সর্বদা মৌলিক ধরণের জন্য ডিফল্ট মান দেয় ... যা হয় নাল রেফারেন্স, নাল মান মানের প্রকারের নাল মান, বা নন-অযোগ্য মান ধরণের প্রাকৃতিক "সমস্ত শূন্য" মান।

এটি কি এমন কোনও নির্দিষ্ট উপায়ে সেট আপ করা যেতে পারে যাতে কোনও নির্দিষ্ট প্রশ্নের জন্য কোনও মান না থাকলে কিছু পূর্বনির্ধারিত মান ডিফল্ট মান হিসাবে ফিরে আসে?

রেফারেন্স ধরণের জন্য, আপনি কেবল ব্যবহার করতে পারেন:

var result = query.FirstOrDefault() ?? otherDefaultValue;

অবশ্যই এই হবে এছাড়াও আপনি "অন্যান্য ডিফল্ট মান" দিতে প্রথম মান উপস্থিত, কিন্তু একটি নাল রেফারেন্স ...


আমি জানি যে প্রশ্নটি রেফারেন্স প্রকারের জন্য জিজ্ঞাসা করে তবে যখন উপাদানগুলির মান ধরণের হয় তখন আপনার সমাধান কার্যকর হয় না int। আমি অনেক ব্যবহার পছন্দ করা DefaultIfEmpty: src.Where(filter).DefaultIfEmpty(defaultValue).First()। উভয় মানের ধরণ এবং রেফারেন্স ধরণের জন্য কাজ করে।
কেএফএল

@ কেএফএল: অ-অযোগ্য মান ধরণের জন্য আমি সম্ভবত এটি ব্যবহার করতাম - তবে এটি নমনীয় ক্ষেত্রে আরও দীর্ঘায়িত হয়।
জন স্কিটি

ডিফল্ট শূন্য হলে রিটার্নের ধরণের উপর দুর্দান্ত নিয়ন্ত্রণ ... :)
সুন্দরারা প্রুবু

"না। বরং এটি উপাদান ধরণের জন্য সর্বদা ডিফল্ট মানটি ফিরিয়ে দেয় ..." - এটি আমার পক্ষে এটি ঘটেছিল, আসলে .. যেমন আমি প্রয়োজন অনুমান করে আপনি কোনও ডিফল্ট মান প্রদান করতে পারব বলে ধরে ফাংশন নামের অর্থকেও বাতিল করে দিয়েছি
যিশু ক্যাম্পন

আমি এই পদ্ধতির সত্যই পছন্দ করেছি, তবে আমি "ফানক <টি> বিকল্প" দ্বারা "টি বিকল্প" পরিবর্তন করেছি এবং তারপরে "বিকল্প () ফিরিয়ে আনি;" আমার প্রয়োজন না হলে আমি অতিরিক্ত বস্তু উত্পন্ন করি না। বিশেষত কার্যকর যদি ফাংশনটি একাধিকবার ডাকা হয়, তবে নির্মাণকারীটি ধীর হয় না বা বিকল্প বিকল্পটি ধরণের স্মৃতি প্রচুর পরিমাণে নেয়।
ড্যান ভায়োলেট স্যাগমিলার

64

আপনি DefaultIfEmpty প্রথমে অনুসরণ করতে পারেন :

T customDefault = ...;
IEnumerable<T> mySequence = ...;
mySequence.DefaultIfEmpty(customDefault).First();

আমি ধারণা ভালবাসা DefaultIfEmpty- এটা সব API গুলি প্রয়োজন যে একটি ডিফল্ট উল্লেখ করা সঙ্গে কাজ করে: First(), Last(), ইত্যাদি একটি ব্যবহারকারী হিসাবে, আপনার মনে রাখতে যা API গুলি ডিফল্ট যা না নির্দিষ্ট করার অনুমোদন দেবে প্রয়োজন হবে না। খুবই ভদ্র!
কেএফএল

এটি খুব নীড় উত্তর।
জেসি উইলিয়ামস

19

ফার্স্টআরডিফল্টের জন্য ডকুমেন্টেশন থেকে

উত্স খালি থাকলে [রিটার্ন] ডিফল্ট (টিএসোর্স);

ডিফল্ট (টি) এর জন্য ডকুমেন্টেশন থেকে :

ডিফল্ট কীওয়ার্ড, যা রেফারেন্স ধরণের জন্য শূন্য এবং সংখ্যাগত মানের ধরণের জন্য শূন্য ফিরে আসবে। স্ট্রাক্টগুলির জন্য, এটি স্ট্রাক্টের প্রতিটি সদস্য শূন্য বা শূন্যে ফেরত দেবে সেগুলি মান বা রেফারেন্স ধরণের কিনা তার উপর নির্ভর করে। মূল্যহীন মান প্রকারের জন্য, ডিফল্ট একটি সিস্টেম দেয় ul ননযোগ্য, যা কোনও স্ট্রকের মতো শুরু হয়।

সুতরাং, টাইপটি কোনও রেফারেন্স বা মান প্রকারের উপর নির্ভর করে ডিফল্ট মান নাল বা 0 হতে পারে তবে আপনি ডিফল্ট আচরণটি নিয়ন্ত্রণ করতে পারবেন না।


6

@ স্লোথ দ্বারা মন্তব্য থেকে অনুলিপি করা

পরিবর্তে YourCollection.FirstOrDefault(), আপনি YourCollection.DefaultIfEmpty(YourDefault).First()উদাহরণস্বরূপ ব্যবহার করতে পারেন ।

উদাহরণ:

var viewModel = new CustomerDetailsViewModel
    {
            MainResidenceAddressSection = (MainResidenceAddressSection)addresses.DefaultIfEmpty(new MainResidenceAddressSection()).FirstOrDefault( o => o is MainResidenceAddressSection),
            RiskAddressSection = addresses.DefaultIfEmpty(new RiskAddressSection()).FirstOrDefault(o => !(o is MainResidenceAddressSection)),
    };

2
নোট করুন যে DefaultIfEmptyসংগ্রহটি খালি থাকলে ডিফল্ট ফিরিয়ে দেয় (০ টি আইটেম রয়েছে) আপনি যদি Firstউদাহরণের মতো মিলে যায় এমন ভাবের সাথে ব্যবহার করেন এবং সেই শর্তটি কোনও আইটেম খুঁজে না পান তবে আপনার ফেরতের মান খালি থাকবে be
ওরিওলবিজি

5

আপনি এটি করতে পারেন

    Band[] objects = { new Band { Name = "Iron Maiden" } };
    first = objects.Where(o => o.Name == "Slayer")
        .DefaultIfEmpty(new Band { Name = "Black Sabbath" })
        .FirstOrDefault();   // returns "Black Sabbath" 

এটি কেবল লিনাক - ইয়েপি ব্যবহার করে!


2
এই উত্তর এবং ভিটামিন সি এর উত্তরের মধ্যে একমাত্র পার্থক্য হ'ল এটির FirstOrDefaultপরিবর্তে এটি ব্যবহার করে First। মতে msdn.microsoft.com/en-us/library/bb340482.aspx , প্রস্তাবিত ব্যবহারের হয়First
ড্যানিয়েল

5

প্রকৃতপক্ষে, আমি NullReferenceExceptionযখন সংগ্রহগুলি নিয়ে কাজ করছি তখন এড়াতে আমি দুটি উপায় ব্যবহার করি:

public class Foo
{
    public string Bar{get; set;}
}
void Main()
{
    var list = new List<Foo>();
    //before C# 6.0
    string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
    //C# 6.0 or later
    var barCSharp6 = list.FirstOrDefault()?.Bar;
}

সি # 6.0 বা তার পরে:

সদস্য অ্যাক্সেস নাল-শর্তসাপেক্ষ অপারেটর ডকুমেন্টেশন সম্পাদন করার আগে শূন্য হয় কিনা তা ব্যবহার ?.বা ?[পরীক্ষার জন্য

উদাহরণ: var barCSharp6 = list.FirstOrDefault()?.Bar;

সি # পুরানো সংস্করণ:

DefaultIfEmpty()ক্রমটি খালি থাকলে একটি ডিফল্ট মান পুনরুদ্ধার করতে ব্যবহার করুন । এমএসডিএন ডকুমেন্টেশন

উদাহরণ: string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;


1
নাল প্রচারের অপারেটরটিকে এক্সপ্রেশন ট্রি ল্যাম্বায় অনুমোদিত নয়।
Lars335

1

পরিবর্তে YourCollection.FirstOrDefault(), আপনি YourCollection.DefaultIfEmpty(YourDefault).First()উদাহরণস্বরূপ ব্যবহার করতে পারেন ।


আপনি যখন মনে করেন যে এটি সহায়ক ছিল, আপনি উন্নত করতে পারেন। এটি কোনও উত্তর নয়।
janagy02

1

আমার ঠিক একইরকম পরিস্থিতি ছিল এবং আমি এমন সমাধানের সন্ধান করছিলাম যা প্রতিবার কলারের পাশে যত্ন নেওয়ার পরিবর্তে আমাকে বিকল্প ডিফল্ট মান ফেরত দিতে দেয়। লিনক আমরা যা চাই তা সমর্থন না করার ক্ষেত্রে আমরা সাধারণত যা করি তা হ'ল এটি একটি নতুন এক্সটেনশন লিখুন যা এটির যত্ন নেয়। আমি কি করেছি। আমি এখানে যা এলাম তা এখানে (যদিও পরীক্ষিত নয়):

public static class EnumerableExtensions
{
    public static T FirstOrDefault<T>(this IEnumerable<T> items, T defaultValue)
    {
        foreach (var item in items)
        {
            return item;
        }
        return defaultValue;
    }

    public static T FirstOrDefault<T>(this IEnumerable<T> items, Func<T, bool> predicate, T defaultValue)
    {
        return items.Where(predicate).FirstOrDefault(defaultValue);
    }

    public static T LastOrDefault<T>(this IEnumerable<T> items, T defaultValue)
    {
        return items.Reverse().FirstOrDefault(defaultValue);
    }

    public static T LastOrDefault<T>(this IEnumerable<T> items, Func<T, bool> predicate, T defaultValue)
    {
        return items.Where(predicate).LastOrDefault(defaultValue);
    }
}

0

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

static class ExtensionsThatWillAppearOnIEnumerables
{
    public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> predicate, Func<T> alternate)
    {
        var thing = source.FirstOrDefault(predicate);
        if (thing != null)
            return thing;
        return alternate();
    }
}

এটি আমাকে এটিকে ইনলাইন হিসাবে কল করতে দেয় আমার নিজের উদাহরণ দিয়ে যা নিয়ে আমার সমস্যা হয়েছিল:

_controlDataResolvers.FirstOr(x => x.AppliesTo(item.Key), () => newDefaultResolver()).GetDataAsync(conn, item.ToList())

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


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