.NET- এ পরিবর্তনের পরিবর্তনের জন্য একটি নির্দিষ্ট গাইড to


227

আমি নেট / সিএলআর, এবং বিশেষত এপিআই পরিবর্তন কীভাবে ক্লায়েন্ট অ্যাপ্লিকেশনগুলিকে ভেঙে দেয় না বা কীভাবে এপিআই পরিবর্তন করে তা সম্পর্কিত যতটা সম্ভব তথ্য সংগ্রহ করতে চাই। প্রথমে কিছু শর্ত সংজ্ঞায়িত করা যাক:

এপিআই পরিবর্তন - এর যে কোনও পাবলিক সদস্য সহ কোনও প্রকারের সর্বজনীনভাবে দৃশ্যমান সংজ্ঞায়িত পরিবর্তন। এর মধ্যে রয়েছে টাইপ এবং সদস্যের নাম পরিবর্তন করা, এক প্রকারের বেস টাইপ পরিবর্তন করা, কোনও প্রকারের প্রয়োগকৃত ইন্টারফেসের তালিকা থেকে ইন্টারফেস যুক্ত করা / অপসারণ, সদস্যদের যোগ করা / অপসারণ (ওভারলোড সহ), সদস্যের দৃশ্যমানতা পরিবর্তনকরণ, পদ্ধতি পরিবর্তনের পদ্ধতি এবং পরামিতি টাইপ করা, ডিফল্ট মান যুক্ত করা পদ্ধতির পরামিতিগুলির জন্য, প্রকার এবং সদস্যগুলিতে বৈশিষ্ট্যগুলি যুক্ত / অপসারণ এবং প্রকার এবং সদস্যগুলিতে জেনেরিক ধরণের পরামিতি যুক্ত / সরানো (আমি কি কিছু মিস করেছি?)। এটিতে সদস্য সংস্থাগুলিতে কোনও পরিবর্তন বা ব্যক্তিগত সদস্যদের কোনও পরিবর্তন অন্তর্ভুক্ত নয় (যেমন আমরা প্রতিচ্ছবিটিকে বিবেচনায় নিই না)।

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

উত্স-স্তরের বিরতি - একটি এপিআই পরিবর্তন যা এপিআই - র পুরানো সংস্করণের সাথে সংকলন করার জন্য বিদ্যমান কোডের ফলস্বরূপ নতুন সংস্করণটি সংকলন করে না results ইতিমধ্যে সংকলিত ক্লায়েন্ট অ্যাসেমব্লিগুলি আগের মতোই কাজ করে। উদাহরণ: একটি নতুন ওভারলোড যুক্ত করা যা পদ্ধতি কলগুলিতে দ্ব্যর্থহীনতার ফলস্বরূপ হতে পারে যা পূর্ববর্তীগুলিতে দ্ব্যর্থহীন ছিল।

উত্স-স্তরের শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন - একটি এপিআই পরিবর্তন যা এপিআই-র পুরানো সংস্করণের বিরুদ্ধে সংকলন করার জন্য বিদ্যমান কোডের ফলাফল হিসাবে নিঃশব্দে এর শব্দার্থবিজ্ঞান পরিবর্তন করে, যেমন একটি ভিন্ন পদ্ধতি কল করে। কোডটি তবে কোনও সতর্কতা / ত্রুটি সহ সংকলন চালিয়ে যাওয়া উচিত এবং পূর্বে সংকলিত সমাবেশগুলি আগের মতো কাজ করা উচিত। উদাহরণ: বিদ্যমান শ্রেণিতে একটি নতুন ইন্টারফেস বাস্তবায়ন করা হচ্ছে যার ফলে ওভারলোড রেজোলিউশনের সময় আলাদা ওভারলোড চয়ন করা হয়।

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

এটিকে কিক স্টার্ট করার কয়েকটি উদাহরণ:

নতুন পদ্ধতির ওভারলোডগুলি যুক্ত করা হচ্ছে

দয়া করে: উত্স-স্তরের বিরতি

ভাষাগুলি প্রভাবিত: সি #, ভিবি, এফ #

পরিবর্তনের আগে এপিআই:

public class Foo
{
    public void Bar(IEnumerable x);
}

পরিবর্তনের পরে এপিআই:

public class Foo
{
    public void Bar(IEnumerable x);
    public void Bar(ICloneable x);
}

পরিবর্তনের আগে কাজ করার নমুনা ক্লায়েন্ট কোড এবং এর পরে ভেঙে গেছে:

new Foo().Bar(new int[0]);

নতুন অন্তর্ভুক্ত রূপান্তর অপারেটর ওভারলোডগুলি যুক্ত করা হচ্ছে

দয়া করে: উত্স-স্তরের বিরতি।

ভাষাগুলি প্রভাবিত: সি #, ভিবি

ভাষা প্রভাবিত হয় না: F #

পরিবর্তনের আগে এপিআই:

public class Foo
{
    public static implicit operator int ();
}

পরিবর্তনের পরে এপিআই:

public class Foo
{
    public static implicit operator int ();
    public static implicit operator float ();
}

পরিবর্তনের আগে কাজ করার নমুনা ক্লায়েন্ট কোড এবং এর পরে ভেঙে গেছে:

void Bar(int x);
void Bar(float x);
Bar(new Foo());

নোটস: এফ # টি ভাঙ্গা হয়নি, কারণ এতে ওভারলোডেড অপারেটরগুলির জন্য কোনও ভাষা স্তরের সমর্থন নেই, সুস্পষ্ট বা অন্তর্নিহিতও নয় - উভয়ই সরাসরি op_Explicitএবং op_Implicitপদ্ধতি হিসাবে কল করতে হবে ।

নতুন উদাহরণ পদ্ধতি যুক্ত করা হচ্ছে

দয়া করে: উত্স-স্তরের শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন।

ভাষাগুলি প্রভাবিত: সি #, ভিবি

ভাষা প্রভাবিত হয় না: F #

পরিবর্তনের আগে এপিআই:

public class Foo
{
}

পরিবর্তনের পরে এপিআই:

public class Foo
{
    public void Bar();
}

নমুনা ক্লায়েন্ট কোড যা একটি শান্ত শব্দার্থবিজ্ঞানের পরিবর্তনে ভোগ করে:

public static class FooExtensions
{
    public void Bar(this Foo foo);
}

new Foo().Bar();

নোটস: এফ # টি ভাঙ্গা হয়নি, কারণ এটির জন্য ভাষা স্তর সমর্থন নেই ExtensionMethodAttribute, এবং সিএলএস এক্সটেনশন পদ্ধতিগুলি স্ট্যাটিক পদ্ধতি হিসাবে ডাকা প্রয়োজন।


অবশ্যই মাইক্রোসফ্ট ইতিমধ্যে এটি কভার করেছে ... এমএসডিএন.মাইক্রোসফট /en-us/netframework/aa570326.aspx
রবার্ট হার্ভে

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

এই "বিরতি" বিভাগের যে কোনওটিতে, সমস্যাটি কেবল রানটাইমে স্পষ্ট হয়ে উঠবে?
রোহিত

1
হ্যাঁ, "বাইনারি ব্রেক" বিভাগ। সেক্ষেত্রে আপনার সমাবেশের সমস্ত সংস্করণের বিরুদ্ধে ইতিমধ্যে আপনার একটি তৃতীয় পক্ষের সংকলন সংকলিত আছে। আপনি যদি নিজের সমাবেশের নতুন সংস্করণটি স্থানে ফেলে রাখেন, তৃতীয় পক্ষের সমাবেশটি কাজ বন্ধ করে দেয় - হয় এটি রান-টাইমে লোড হয় না, অথবা এটি ভুলভাবে কাজ করে।
পাভেল মিনায়েভ

3
আমি তাদের পোস্ট এবং মন্তব্যগুলিতে ব্লগস.এমএসএনএন
লুকাস ম্যাডন

উত্তর:


42

কোনও পদ্ধতিতে স্বাক্ষর পরিবর্তন করা হচ্ছে

দয়া করে: দ্বি-স্তরের বিরতি

ভাষাগুলি প্রভাবিত: সি # (ভিবি এবং এফ # সম্ভবত, তবে অনির্ধারিত)

পরিবর্তনের আগে এপিআই

public static class Foo
{
    public static void bar(int i);
}

পরিবর্তনের পরে এপিআই

public static class Foo
{
    public static bool bar(int i);
}

পরিবর্তনের আগে কাজ করছে নমুনা ক্লায়েন্ট কোড

Foo.bar(13);

15
প্রকৃতপক্ষে, যদি কেউ কোনও প্রতিনিধি তৈরির চেষ্টা করে তবে এটি উত্স-স্তরের বিরতিও হতে পারে bar
পাভেল মিনায়েভ

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

1
এটি আবার ফিরে যায় যে রিটার্নের ধরণগুলি পদ্ধতির স্বাক্ষরের জন্য গণনা করে না। আপনি কেবলমাত্র রিটার্ন টাইপের ভিত্তিতে দুটি ফাংশন ওভারলোড করতে পারবেন না। একই সমস্যা.
জেসন সংক্ষিপ্ত

1
এই উত্তরের subqestion: কেউ dotnet4 ডিফল্ট মূল্য 'পাবলিক স্ট্যাটিক শূন্য বার (int i = 0) যোগ করার ইঙ্গিত বুঝতে পারে কি;' বা সেই ডিফল্ট মূল্যটিকে অন্য মান থেকে অন্য মানতে পরিবর্তন করতে হবে?
k3b 9

1
যারা এই পৃষ্ঠায় অবতরণ করতে চলেছেন তাদের জন্য আমি সি # (এবং "আমি মনে করি" বেশিরভাগ অন্যান্য ওওপি ভাষাগুলি) মনে করি, রিটার্ন প্রকারগুলি পদ্ধতি স্বাক্ষরে অবদান রাখে না। হ্যাঁ উত্তরটি সঠিক যে স্বাক্ষর পরিবর্তনগুলি বাইনারি স্তর পরিবর্তনে অবদান রাখে। কিন্তু উদাহরণস্বরূপ সঠিক এই প্রোগ্রামটিতে সঠিক উদাহরণ যে আমি মনে করতে পারেন হয় মনে করে না আগে প্রকাশ্য দশমিক যোগফল (ক, int-B int) পর প্রকাশ্য দশমিক SUM (দশমিক একটি, দশমিক খ) কল্যাণকামী এই দুটিই MSDN লিংক পড়ুন 3.6 স্বাক্ষর এবং ওভারলোডিং
ভানু ছাবরা

40

একটি ডিফল্ট মান সহ একটি পরামিতি যুক্ত করা।

ধরণের ব্রেক: বাইনারি-স্তরের বিরতি

কলিং উত্স কোডটি পরিবর্তন করার প্রয়োজন না থাকলেও এটি পুনরায় সংযুক্ত করা দরকার (ঠিক যেমন নিয়মিত প্যারামিটার যুক্ত করার সময়)।

কারণ সি # কলিং অ্যাসেমব্লিতে প্যারামিটারগুলির ডিফল্ট মানগুলি সংকলন করে। এর অর্থ হল যে আপনি যদি পুনরায় সংকলন না করেন তবে আপনি একটি মিসিংমথোডেক্সপশন পাবেন কারণ পুরানো সমাবেশটি কম যুক্তি দিয়ে কোনও পদ্ধতিতে কল করার চেষ্টা করে।

পরিবর্তনের আগে এপিআই

public void Foo(int a) { }

পরিবর্তনের পরে এপিআই

public void Foo(int a, string b = null) { }

নমুনা ক্লায়েন্ট কোড যা পরে ভেঙে যায়

Foo(5);

ক্লায়েন্ট কোডটি Foo(5, null)বাইকোড স্তরে পুনরায় সংযুক্ত করা দরকার । তথাকথিত অ্যাসেমব্লিতে কেবল থাকবে Foo(int, string), না Foo(int)। এটি কারণ ডিফল্ট প্যারামিটার মানগুলি নির্ভুলভাবে একটি ভাষা বৈশিষ্ট্য,। নেট রানটাইম তাদের সম্পর্কে কিছুই জানে না। (এটি ডিফল্ট মানগুলিকে সি # তে সংকলন-সময় ধ্রুবক হতে হবে তাও ব্যাখ্যা করে)।


2
এটি উত্স কোড স্তরের এমনকি একটি ব্রেকিং পরিবর্তন: Func<int> f = Foo;// এটি পরিবর্তিত স্বাক্ষরের সাথে ব্যর্থ হবে
ভাগাস

26

বিশেষত ইন্টারফেসের জন্য একই পরিস্থিতির সাথে পার্থক্যের আলোকে এটি আবিষ্কার করার সময় এইটি খুব অ-স্পষ্ট ছিল। এটি মোটেও বিরতি নয়, তবে এটি যথেষ্ট আশ্চর্যজনক যে আমি এটি অন্তর্ভুক্ত করার সিদ্ধান্ত নিয়েছিলাম:

একটি বেস শ্রেণিতে শ্রেণীর সদস্যদের রিফ্যাক্টরিং

দয়া: বিরতি না!

ভাষা প্রভাবিত: কিছুই নয় (অর্থাত্ কোনওটিই ভাঙা হয়নি)

পরিবর্তনের আগে এপিআই:

class Foo
{
    public virtual void Bar() {}
    public virtual void Baz() {}
}

পরিবর্তনের পরে এপিআই:

class FooBase
{
    public virtual void Bar() {}
}

class Foo : FooBase
{
    public virtual void Baz() {}
}

নমুনা কোড যা পরিবর্তনটি জুড়ে কাজ করে চলেছে (যদিও আমি এটিটি ভেঙে ফেলার আশা করেছিলাম):

// C++/CLI
ref class Derived : Foo
{
   public virtual void Baz() {{

   // Explicit override    
   public virtual void BarOverride() = Foo::Bar {}
};

মন্তব্য:

সি ++ / সিএলই হ'ল একমাত্র নেট ভাষা যা ভার্চুয়াল বেস শ্রেণীর সদস্যদের জন্য স্পষ্টত ইন্টারফেস বাস্তবায়নের অনুরূপ - "স্বচ্ছ ওভাররাইড"। আমি পুরোপুরি প্রত্যাশা করেছিলাম যে একই ধরণের ভাঙ্গনের ফলে যখন ইন্টারফেস সদস্যদের একটি বেস ইন্টারফেসে স্থানান্তরিত করা হয় (যেহেতু স্পষ্টত ওভাররাইডের জন্য উত্পন্ন আইএল সুস্পষ্ট প্রয়োগের জন্য একই)) আমার অবাক করার মতো বিষয়টি নয় - যদিও উত্পন্ন আইএল এখনও নির্দিষ্ট করে না যে BarOverrideওভাররাইডের Foo::Barচেয়েও FooBase::Bar, এসেম্বলি লোডার কোনও অভিযোগ ছাড়াই একে অপরের জন্য সঠিকভাবে স্থান দেওয়ার পক্ষে যথেষ্ট স্মার্ট - স্পষ্টতই, এই বিষয়টি Fooএকটি শ্রেণি যা পার্থক্য তৈরি করে। চিত্রে যান...


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

@ জেরেমি কী ক্ষেত্রে কোডটি ভাঙছে? কোনও বাহ্যিক কলারের বাজে () ব্যবহার কী ভেঙে ফেলবে বা ফু সম্প্রসারিত করার এবং বাজ () কে ওভাররাইড করার চেষ্টা করে এমন লোকদের সাথে এটিই কেবল একটি সমস্যা?
চেসমেডালিয়ন

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

19

এটি একটি "ইন্টারফেস সদস্যদের যোগ / অপসারণ" এর সম্ভবত একটি খুব সম্ভবত-স্পষ্ট বিশেষ কেস এবং আমি বুঝতে পেরেছিলাম যে এটি অন্য একটি মামলার আলোকে এটির নিজের প্রবেশের প্রাপ্য যা আমি পরবর্তী পোস্ট করব। তাই:

ইন্টারফেস সদস্যদের একটি বেস ইন্টারফেসে রিফ্যাক্টরিং

ধরনের: উত্স এবং বাইনারি উভয় স্তরে বিরতি

ভাষাগুলি প্রভাবিত: সি #, ভিবি, সি ++ / সিএলআই, এফ # (উত্স বিরতির জন্য; বাইনারি কোনও কোনও ভাষা প্রাকৃতিকভাবে প্রভাবিত করে)

পরিবর্তনের আগে এপিআই:

interface IFoo
{
    void Bar();
    void Baz();
}

পরিবর্তনের পরে এপিআই:

interface IFooBase 
{
    void Bar();
}

interface IFoo : IFooBase
{
    void Baz();
}

উত্স স্তরে পরিবর্তনের দ্বারা নষ্ট হওয়া নমুনা ক্লায়েন্ট কোড:

class Foo : IFoo
{
   void IFoo.Bar() { ... }
   void IFoo.Baz() { ... }
}

বাইনারি স্তরে পরিবর্তনের মাধ্যমে ভেঙে আসা নমুনা ক্লায়েন্ট কোড;

(new Foo()).Bar();

মন্তব্য:

উত্স স্তরের বিরতির জন্য, সমস্যাটি হ'ল সি #, ভিবি এবং সি ++ / সিএলআই সকলের ইন্টারফেস সদস্য প্রয়োগের ঘোষণায় সঠিক ইন্টারফেসের নাম প্রয়োজন ; সুতরাং, যদি সদস্যটি একটি বেস ইন্টারফেসে স্থানান্তরিত হয়, কোডটি আর সংকলন করবে না।

বাইনারি ব্রেকটি স্পষ্ট বাস্তবায়নের জন্য জেনারেটড আইএলটিতে পুরোপুরি যোগ্যতা অর্জন করার কারণে এবং ইন্টারফেসের নামটিও যথাযথ হওয়া উচিত to

অন্তর্নিহিত বাস্তবায়ন যেখানে উপলব্ধ (যেমন সি # এবং সি ++ / সিএলআই, তবে ভিবি নয়) উত্স এবং বাইনারি উভয় স্তরে সূক্ষ্মভাবে কাজ করবে। পদ্ধতি কলগুলিও ভেঙে যায় না।


এটি সমস্ত ভাষার ক্ষেত্রে সত্য নয়। ভিবির জন্য এটি কোনও ব্রেকিং সোর্স কোড পরিবর্তন নয়। সি # এর জন্য এটি।
জেরেমি

তাহলে Implements IFoo.Barস্বচ্ছভাবে রেফারেন্স দেবে IFooBase.Bar?
পাভেল মিনায়েভ

হ্যাঁ, এটি আসলে রয়েছে, আপনি যখন এটি প্রয়োগ করবেন তখন উত্তরাধিকারী ইন্টারফেসের মাধ্যমে আপনি প্রত্যক্ষ বা অপ্রত্যক্ষভাবে কোনও সদস্যকে উল্লেখ করতে পারেন। তবে এটি সর্বদা একটি ব্রেকিং বাইনারি পরিবর্তন।
জেরেমি

15

গণিত মানগুলিকে পুনরায় সাজানো

বিরতির ধরণ: উত্স-স্তর / বাইনারি-স্তরের শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন

ভাষা প্রভাবিত: সব

পুনরায় সাজানো মানগুলি উত্স স্তরের সামঞ্জস্যতা বজায় রাখবে কারণ আক্ষরিকের একই নাম রয়েছে তবে তাদের সূচক সূচকগুলি আপডেট হবে যা কিছু ধরণের নীরব উত্স-স্তরের বিরতি সৃষ্টি করতে পারে।

আরও খারাপ হ'ল নীরব বাইনারি-স্তরের বিরতি যা চালু করা যেতে পারে যদি ক্লায়েন্ট কোডটি নতুন এপিআই সংস্করণের বিরুদ্ধে পুনরায় সংকলিত না হয়। এনাম মানগুলি সংকলন-সময় ধ্রুবক এবং এগুলির কোনও ব্যবহার ক্লায়েন্ট সমাবেশের আইএল এ বেক করা হয়। এই ক্ষেত্রে সময়ে বিশেষত পাওয়া খুব কঠিন হতে পারে।

পরিবর্তনের আগে এপিআই

public enum Foo
{
   Bar,
   Baz
}

পরিবর্তনের পরে এপিআই

public enum Foo
{
   Baz,
   Bar
}

নমুনা ক্লায়েন্ট কোড যা কাজ করে তবে পরে এটি ভেঙে যায়:

Foo.Bar < Foo.Baz

12

এটি বাস্তবে অনুশীলনের ক্ষেত্রে খুব বিরল জিনিস, তবে তা ঘটলে অবাক করা কিছু হয়।

নতুন অ-ওভারলোড হওয়া সদস্যদের যুক্ত করা হচ্ছে

দয়া করে: উত্স স্তরের বিরতি বা শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন।

ভাষাগুলি প্রভাবিত: সি #, ভিবি

ভাষাগুলি প্রভাবিত হয় না: এফ #, সি ++ / সিএলআই

পরিবর্তনের আগে এপিআই:

public class Foo
{
}

পরিবর্তনের পরে এপিআই:

public class Foo
{
    public void Frob() {}
}

পরিবর্তনের মাধ্যমে ভেঙে আসা নমুনা ক্লায়েন্ট কোড:

class Bar
{
    public void Frob() {}
}

class Program
{
    static void Qux(Action<Foo> a)
    {
    }

    static void Qux(Action<Bar> a)
    {
    }

    static void Main()
    {
        Qux(x => x.Frob());        
    }
}

মন্তব্য:

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

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

নোট করুন যে প্রকারগুলি Fooএবং Barএই উদাহরণে কোনওভাবেই সম্পর্কিত নয়, উত্তরাধিকার দ্বারা বা অন্যথায় নয়। একক পদ্ধতি গোষ্ঠীতে এগুলির ব্যবহার কেবল এটিই ট্রিগার করার জন্য যথেষ্ট এবং যদি এটি ক্লায়েন্ট কোডে ঘটে তবে আপনার এটির কোনও নিয়ন্ত্রণ নেই।

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


9

একটি অন্তর্নিহিত ইন্টারফেস বাস্তবায়নকে একটি সুস্পষ্ট রূপান্তর করুন।

ধরনের বিরতি: উত্স এবং বাইনারি

প্রভাবিত ভাষা: সমস্ত

এটি আসলে কোনও পদ্ধতির অ্যাক্সেসিবিলিটি পরিবর্তনের একটি বৈচিত্র মাত্র - এটি কেবলমাত্র আরও সূক্ষ্ম যেহেতু এই সত্যটিকে উপেক্ষা করা সহজ যে কোনও ইন্টারফেসের পদ্ধতিতে সমস্ত অ্যাক্সেস অগত্যা ইন্টারফেসের ধরণের রেফারেন্সের মাধ্যমে হয় না।

পরিবর্তনের আগে এপিআই:

public class Foo : IEnumerable
{
    public IEnumerator GetEnumerator();
}

পরিবর্তনের পরে এপিআই:

public class Foo : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator();
}

নমুনা ক্লায়েন্ট কোড যা পরিবর্তনের আগে কাজ করে এবং এর পরে ভেঙে যায়:

new Foo().GetEnumerator(); // fails because GetEnumerator() is no longer public

7

সুস্পষ্ট ইন্টারফেস প্রয়োগকে একটি অন্তর্নিহিত রূপে রূপান্তর করুন।

প্রকারের বিরতি: উত্স

প্রভাবিত ভাষা: সমস্ত

একটি স্পষ্টত ইন্টারফেস প্রয়োগের প্রতিসরণকে একটি অন্তর্নিহিত হিসাবে রিফ্যাক্টরিং এটি কীভাবে কোনও এপিআই ভেঙে ফেলতে পারে তা আরও সূক্ষ্ম। পৃষ্ঠতলে, এটি মনে হবে এটি তুলনামূলকভাবে নিরাপদ হওয়া উচিত, তবে উত্তরাধিকারের সাথে মিলিত হলে এটি সমস্যার কারণ হতে পারে।

পরিবর্তনের আগে এপিআই:

public class Foo : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator() { yield return "Foo"; }
}

পরিবর্তনের পরে এপিআই:

public class Foo : IEnumerable
{
    public IEnumerator GetEnumerator() { yield return "Foo"; }
}

নমুনা ক্লায়েন্ট কোড যা পরিবর্তনের আগে কাজ করে এবং এর পরে ভেঙে যায়:

class Bar : Foo, IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator() // silently hides base instance
    { yield return "Bar"; }
}

foreach( var x in new Bar() )
    Console.WriteLine(x);    // originally output "Bar", now outputs "Foo"

দুঃখিত, আমি পুরোপুরি অনুসরণ করি না - অবশ্যই এপিআই পরিবর্তনের আগে স্যাম্পল কোডটি মোটেও সংকলন করবে না, যেহেতু পরিবর্তনের আগে Fooকোনও পাবলিক পদ্ধতি না ছিল GetEnumeratorএবং আপনি পদ্ধতিটিকে কোনও রেফারেন্সের মাধ্যমে কল করছেন Foo.. ।
পাভেল মিনায়েভ

প্রকৃতপক্ষে, আমি স্মৃতি থেকে একটি উদাহরণ সহজ করার চেষ্টা করেছি এবং এটি 'ফুবার' (ক্ষমা ক্ষমা করে) শেষ হয়েছে। আমি কেসটি সঠিকভাবে প্রদর্শন করার জন্য উদাহরণটি আপডেট করেছি (এবং সংকলনযোগ্য হবে)।
এল বুশকিন

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

আপনি ভুলে গিয়েছেন yield return "Bar":) তবে হ্যাঁ, আমি দেখতে পাচ্ছি যে এটি এখন কোথায় চলেছে - foreachসর্বদা সর্বজনীন নামকরণকে কল করে GetEnumerator, যদিও এটি বাস্তব বাস্তবায়ন না হয় IEnumerable.GetEnumerator। এটি আরও একটি কোণ বলে মনে হচ্ছে: এমনকি যদি আপনার কেবল একটি শ্রেণি থাকে এবং এটি IEnumerableস্পষ্টভাবে প্রয়োগ করে , এর অর্থ এটির নামকরণ GetEnumeratorকরা একটি পাবলিক পদ্ধতি যুক্ত করার জন্য এটি একটি উত্স পরিবর্তনের পরিবর্তন , কারণ এখন foreachইন্টারফেস প্রয়োগের ক্ষেত্রে এই পদ্ধতিটি ব্যবহার করবে। এছাড়াও, একই সমস্যা IEnumeratorবাস্তবায়নের জন্য প্রযোজ্য ...
পাভেল মিনায়েভ

6

একটি সম্পত্তি একটি ক্ষেত্র পরিবর্তন

বিরতি ধরনের: এপিআই

ভাষাগুলি প্রভাবিত: ভিজ্যুয়াল বেসিক এবং সি # *

তথ্য: আপনি যখন কোনও সাধারণ ক্ষেত্র বা ভেরিয়েবলটি ভিজ্যুয়াল বেসিকের কোনও সম্পত্তিতে পরিবর্তন করেন, সেই সদস্যের যে কোনও উপায়ে উল্লেখ করে বাইরের কোডটি পুনরায় সংযুক্ত করা দরকার।

পরিবর্তনের আগে এপিআই:

Public Class Foo    
    Public Shared Bar As String = ""    
End Class

পরিবর্তনের পরে এপিআই:

Public Class Foo
    Private Shared _Bar As String = ""
    Public Shared Property Bar As String
        Get
            Return _Bar
        End Get
        Set(value As String)
            _Bar = value
        End Set
    End Property
End Class    

নমুনা ক্লায়েন্ট কোড যা কাজ করে তবে পরে এটি ভেঙে যায়:

Foo.Bar = "foobar"

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

5

নাম স্থান সংযোজন

উত্স-স্তরের বিরতি / উত্স-স্তরের শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন

ভিবি.নেটে নেমস্পেস রেজোলিউশন যেভাবে কাজ করে তার কারণে, একটি লাইব্রেরিতে নেমস্পেস যুক্ত করা ভিজ্যুয়াল বেসিক কোডের কারণ হতে পারে যা এপিআই-এর পূর্ববর্তী সংস্করণ সহ নতুন সংস্করণ দিয়ে সংকলন না করে।

নমুনা ক্লায়েন্ট কোড:

Imports System
Imports Api.SomeNamespace

Public Class Foo
    Public Sub Bar()
        Dim dr As Data.DataRow
    End Sub
End Class

যদি API এর একটি নতুন সংস্করণ নেমস্পেস যোগ করে Api.SomeNamespace.Dataতবে উপরের কোডটি সংকলন করবে না।

প্রকল্প-স্তরের নেমস্পেস আমদানি নিয়ে এটি আরও জটিল হয়ে ওঠে। যদি Imports Systemউপরের কোড থেকে বাদ দেওয়া Systemহয় তবে প্রকল্পের স্তরে নেমস্পেসটি আমদানি করা হয় তবে কোডটি তবুও ত্রুটির কারণ হতে পারে।

যাইহোক, যদি এপিআই DataRowএর Api.SomeNamespace.Dataনামস্থানে কোনও শ্রেণি অন্তর্ভুক্ত করে , তবে কোডটি সংকলিত হবে তবে এপিআই-র পুরানো সংস্করণটি সংকলিত হবে এবং যখন এপিআই-র নতুন সংস্করণটি সংকলিত drহবে System.Data.DataRowতখন এর উদাহরণ হতে পারে Api.SomeNamespace.Data.DataRow

যুক্তি পুনর্নবীকরণ

উত্স-স্তরের বিরতি

আর্গুমেন্টের নাম পরিবর্তন করা সংস্করণ 7 (?) (। নেট সংস্করণ 1?) এবং গ # সংস্করণ 4 (। নেট সংস্করণ 4) থেকে নেট # নেট থেকে একটি ভঙ্গ পরিবর্তন।

পরিবর্তনের আগে এপিআই:

namespace SomeNamespace {
    public class Foo {
        public static void Bar(string x) {
           ...
        }
    }
}

পরিবর্তনের পরে এপিআই:

namespace SomeNamespace {
    public class Foo {
        public static void Bar(string y) {
           ...
        }
    }
}

নমুনা ক্লায়েন্ট কোড:

Api.SomeNamespace.Foo.Bar(x:"hi"); //C#
Api.SomeNamespace.Foo.Bar(x:="hi") 'VB

রেফারেন্স পরামিতি

উত্স-স্তরের বিরতি

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

পরিবর্তনের আগে এপিআই:

namespace SomeNamespace {
    public class Foo {
        public static void Bar(string x) {
           ...
        }
    }
}

পরিবর্তনের পরে এপিআই:

namespace SomeNamespace {
    public class Foo {
        public static void Bar(string x) {
           ...
        }
        public static void Bar(ref string x) {
           ...
        }
    }
}

নমুনা ক্লায়েন্ট কোড:

Api.SomeNamespace.Foo.Bar(str)

সম্পত্তি পরিবর্তনের ক্ষেত্র

বাইনারি-স্তরের বিরতি / উত্স-স্তরের বিরতি

সুস্পষ্ট বাইনারি-স্তরের বিরতি ছাড়াও, যদি সদস্যটি রেফারেন্স দ্বারা কোনও পদ্ধতিতে পাস করা হয় তবে এটি উত্স-স্তরের বিরতি সৃষ্টি করতে পারে।

পরিবর্তনের আগে এপিআই:

namespace SomeNamespace {
    public class Foo {
        public int Bar;
    }
}

পরিবর্তনের পরে এপিআই:

namespace SomeNamespace {
    public class Foo {
        public int Bar { get; set; }
    }
}

নমুনা ক্লায়েন্ট কোড:

FooBar(ref Api.SomeNamespace.Foo.Bar);

4

এপিআই পরিবর্তন:

  1. [অপ্রচলিত] বৈশিষ্ট্য যুক্ত করা (আপনি এটিকে গুণাবলীর উল্লেখ করে কভার করেছেন; তবে সতর্কতা-হিসাবে-ত্রুটি ব্যবহার করার সময় এটি একটি ব্রেকিং পরিবর্তন হতে পারে))

দ্বি-স্তরের বিরতি:

  1. এক প্রকার থেকে অন্য সমাবেশে একটি প্রকার সরিয়ে নেওয়া
  2. কোনও প্রকারের নাম স্থান পরিবর্তন করা
  3. অন্য সমাবেশ থেকে একটি বেস শ্রেণীর ধরণ যুক্ত করা হচ্ছে।
  4. একটি নতুন সদস্য যুক্ত করা (ইভেন্ট সুরক্ষিত) যা অন্য সমাবেশ থেকে (ক্লাস 2) কোনও টেমপ্লেট আর্গুমেন্ট বাধা হিসাবে ব্যবহার করে।

    protected void Something<T>() where T : Class2 { }
  5. ক্লাসটি এই শ্রেণীর জন্য টেমপ্লেট আর্গুমেন্ট হিসাবে ব্যবহৃত হয় যখন অন্য অ্যাসেমব্লিতে কোনও ধরণের থেকে প্রাপ্ত শিশু শ্রেণি (Class3) পরিবর্তন করা হয়।

    protected class Class3 : Class2 { }
    protected void Something<T>() where T : Class3 { }

উত্স-স্তরের শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন:

  1. সমান (), গেটহ্যাশকোড (), বা টসস্ট্রিং () এর ওভাররাইড যুক্ত / অপসারণ / পরিবর্তন করা

(এগুলি কোথায় ফিট তা নিশ্চিত নয়)

স্থাপনার পরিবর্তনগুলি:

  1. নির্ভরতা / রেফারেন্স যুক্ত করা / অপসারণ করা
  2. নতুন সংস্করণে নির্ভরতা আপডেট করা
  3. X86, Itanium, x64, বা anycpu এর মধ্যে 'টার্গেট প্ল্যাটফর্ম' পরিবর্তন করা হচ্ছে
  4. আলাদা ফ্রেমওয়ার্ক ইনস্টল করে বিল্ডিং / টেস্টিং (উদাহরণস্বরূপ। নেট 2.0 বাক্সে 3.5 ইনস্টল করা এপিআই কলগুলিকে অনুমতি দেয় যার পরে নেট নেট এসপি 2 প্রয়োজন)

বুটস্ট্র্যাপ / কনফিগারেশন পরিবর্তন:

  1. কাস্টম কনফিগারেশন বিকল্পগুলি (যেমন App.config সেটিংস) যুক্ত করা / সরানো / পরিবর্তন করা হচ্ছে
  2. আজকের অ্যাপ্লিকেশনগুলিতে আইওসি / ডিআই-র ভারী ব্যবহারের সাথে, ডিআই নির্ভর কোডের জন্য পুনরায় কনফিগার করতে এবং / অথবা বুটস্ট্র্যাপিং কোডটি পরিবর্তন করা দরকার।

হালনাগাদ:

দুঃখিত, আমি বুঝতে পারি নি যে এটি আমার জন্য ভেঙে যাওয়ার একমাত্র কারণ হ'ল আমি সেগুলি টেম্পলেট সীমাবদ্ধতায় ব্যবহার করেছি।


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

সেই "টাইপফোরওয়ার্ডটো" আমার কাছে খবর, আমি এটি পরীক্ষা করে দেখব। অন্য হিসাবে, আমি এতে 100% নই ... আমাকে তিরস্কার করতে পারে কিনা তা দেখতে দিন এবং আমি পোস্টটি আপডেট করব।
csharptest.net

সুতরাং, -Werrorরিলিজ টার্বলগুলি দিয়ে আপনি যে বিল্ডসিস্টেমটি প্রেরণ করবেন তা জোর করবেন না । এই পতাকাটি কোড বিকাশকারীদের পক্ষে সবচেয়ে বেশি সহায়ক এবং বেশিরভাগ ক্ষেত্রে গ্রাহকের পক্ষে অসহায়।
বিনকি

@ বিনকি দুর্দান্ত পয়েন্ট, সতর্কতাগুলিকে ত্রুটি হিসাবে বিবেচনা করা কেবলমাত্র ডিইবিইউজি বিল্ডে যথেষ্ট হওয়া উচিত।
csharptest.net

3

ডিফল্ট পরামিতিগুলির ব্যবহারের জন্য ওভারলোড পদ্ধতি যুক্ত করা

বিরতির ধরণ: উত্স-স্তরের শান্ত শব্দার্থবিজ্ঞানের পরিবর্তন

কারণ সংকলক কলিং সাইডে ডিফল্ট মান সহ একটি স্পষ্ট কলটিতে অনুপস্থিত ডিফল্ট প্যারামিটার মানগুলির সাথে কলগুলি রূপান্তর করে, বিদ্যমান সংকলিত কোডের জন্য সামঞ্জস্যতা দেওয়া হয়; পূর্ববর্তী সমস্ত সংকলিত কোডের জন্য সঠিক স্বাক্ষর সহ একটি পদ্ধতি পাওয়া যাবে।

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

পরিবর্তনের আগে এপিআই

  public int MyMethod(int mandatoryParameter, int optionalParameter = 0)
  {
     return mandatoryParameter + optionalParameter;
  }    

পরিবর্তনের পরে এপিআই

  public int MyMethod(int mandatoryParameter, int optionalParameter)
  {
     return mandatoryParameter + optionalParameter;
  }

  public int MyMethod(int mandatoryParameter)
  {
     return MyMethod(mandatoryParameter, 0);
  }

নমুনা কোড যা এখনও কাজ করবে

  public int CodeNotDependentToNewVersion()
  {
     return MyMethod(5, 6); 
  }

সংকলনের সময় নমুনা কোড যা এখন নতুন সংস্করণের উপর নির্ভরশীল

  public int CodeDependentToNewVersion()
  {
     return MyMethod(5); 
  }

1

একটি ইন্টারফেস নামকরণ

বিরতির কিন্ডা: উত্স এবং বাইনারি

প্রভাবিত ভাষা: সম্ভবত সমস্ত, সি # তে পরীক্ষিত tested

পরিবর্তনের আগে এপিআই:

public interface IFoo
{
    void Test();
}

public class Bar
{
    IFoo GetFoo() { return new Foo(); }
}

পরিবর্তনের পরে এপিআই:

public interface IFooNew // Of the exact same definition as the (old) IFoo
{
    void Test();
}

public class Bar
{
    IFooNew GetFoo() { return new Foo(); }
}

নমুনা ক্লায়েন্ট কোড যা কাজ করে তবে পরে এটি ভেঙে যায়:

new Bar().GetFoo().Test(); // Binary only break
IFoo foo = new Bar().GetFoo(); // Source and binary break

1

নালাইযোগ্য ধরণের একটি পরামিতি সহ ওভারলোডিং পদ্ধতি

দয়া করে: উত্স-স্তরের বিরতি

ভাষাগুলি প্রভাবিত: সি #, ভিবি

পরিবর্তনের আগে এপিআই:

public class Foo
{
    public void Bar(string param);
}

পরিবর্তনের পরে এপিআই:

public class Foo
{
    public void Bar(string param);
    public void Bar(int? param);
}

পরিবর্তনের আগে কাজ করা নমুনা ক্লায়েন্ট কোড এবং এর পরে ভেঙে গেছে:

new Foo().Bar(null);

ব্যতিক্রম: কলটি নিম্নোক্ত পদ্ধতি বা বৈশিষ্ট্যের মধ্যে অস্পষ্ট।


0

একটি এক্সটেনশন পদ্ধতিতে প্রচার

দয়া করে: উত্স-স্তরের বিরতি

ভাষাগুলি প্রভাবিত: সি # ভি 6 এবং উচ্চতর (সম্ভবত অন্যরা?)

পরিবর্তনের আগে এপিআই:

public static class Foo
{
    public static void Bar(string x);
}

পরিবর্তনের পরে এপিআই:

public static class Foo
{
    public void Bar(this string x);
}

পরিবর্তনের আগে কাজ করার নমুনা ক্লায়েন্ট কোড এবং এর পরে ভেঙে গেছে:

using static Foo;

class Program
{
    static void Main() => Bar("hello");
}

আরও তথ্য: https://github.com/dotnet/csharplang/issues/665

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