পদ্ধতি স্বাক্ষরে নতুন কীওয়ার্ড


113

রিফ্যাক্টরিং করার সময়, আমি নীচের উদাহরণের মতো একটি পদ্ধতি তৈরি করে শেষ করেছি। সরলতার জন্য ডেটাটাইপ পরিবর্তন করা হয়েছে।

আমার আগের একটি অ্যাসাইনমেন্ট স্টেটমেন্ট ছিল:

MyObject myVar = new MyObject();

এটি দুর্ঘটনাক্রমে এটিকে রিফেক্টর করা হয়েছিল:

private static new MyObject CreateSomething()
{
  return new MyObject{"Something New"};
}

এটি আমার পক্ষ থেকে কাটা / পেস্ট ত্রুটির ফলস্বরূপ ছিল, তবে এর newকীওয়ার্ডটি private static newবৈধ এবং সংকলিত।

প্রশ্ন : newকীওয়ার্ডটি কোনও পদ্ধতিতে স্বাক্ষর করে? আমি ধরে নিলাম এটি সি # 3.0 তে কিছু চালু হয়েছে?

এর থেকে কীভাবে আলাদা override?


5
পদ্ধতিটি আড়াল করার আকাঙ্ক্ষার
এরিক লিপার্ট

2
@ এরিক .. দুর্দান্ত পোস্ট। আমি কখনই পদ্ধতিটি সেভাবে লুকানোর কথা ভাবি নি, যেমন হ্যাঁ, বস্তুটি একটি জিনিস, তবে আমরা এখন এটিকে অন্য কিছু হিসাবে উপস্থাপন করছি, সুতরাং আমরা যে বিষয়টি এএস উপস্থাপন করছি তার আচরণ চাই। চতুর ...
বিফ্রি

1
ভবিষ্যতে একটি সদৃশ প্রশ্ন এবং আমি কিছু বিশদে উত্তর দেওয়ার চেষ্টা করেছি: সি # তে নতুন কীওয়ার্ডটি ব্যবহার করুন
কেন কিন

1
newকোনও পদ্ধতিতে (বা অন্যান্য ধরণের সদস্য) এএ মডিফায়ার হিসাবে ব্যবহার করা "সি # 3.0 এ প্রবর্তিত কিছু" নয়। এটি তখনও সি # এর প্রথম সংস্করণ থেকেই রয়েছে।
জেপ্পে স্টিগ নীলসেন

1
এসও-তে এই প্রশ্নের 4 টি সদৃশ রয়েছে। আমার মতে, এটি আপনাকে সর্বোত্তম বোঝাপড়া দেবে: স্ট্যাকওভারফ্লো . com / প্রশ্নগুলি / ৩১১৮৮৮৮৮/২ । এটির উত্তর @ এরিকলিপার্ট দিয়েছেন।
রাইকোল আমারো

উত্তর:


101

এমএসডিএন থেকে নতুন কীওয়ার্ড রেফারেন্স:

এমএসডিএন রেফারেন্স

এখানে নেট থেকে একটি মাইক্রোসফ্ট এমভিপি থেকে পাওয়া একটি উদাহরণ পাওয়া যায় যা ভালভাবে বোঝায়: লিঙ্ক টু অরিজিনাল

public class A
{
   public virtual void One();
   public void Two();
}

public class B : A
{
   public override void One();
   public new void Two();
}

B b = new B();
A a = b as A;

a.One(); // Calls implementation in B
a.Two(); // Calls implementation in A
b.One(); // Calls implementation in B
b.Two(); // Calls implementation in B

ওভাররাইড শুধুমাত্র খুব নির্দিষ্ট ক্ষেত্রে ব্যবহার করা যেতে পারে। এমএসডিএন থেকে:

আপনি একটি অ-ভার্চুয়াল বা স্ট্যাটিক পদ্ধতি ওভাররাইড করতে পারবেন না। ওভাররাইড বেস পদ্ধতিটি ভার্চুয়াল, বিমূর্ত বা ওভাররাইড হতে হবে।

সুতরাং 'নতুন' কীওয়ার্ডটি আপনাকে ভার্চুয়াল এবং স্থিতিশীল পদ্ধতিগুলিকে 'ওভাররাইড' করতে দেয় allow


4
আমি কেবল আপনার নমুনাটি চালাই .. এটি ওভাররাইড হয়ে যাবে এমনকি আপনি "নতুন" নির্দিষ্ট করে না, তাই না?
মাইকেল সিঙ্ক

2
@ মিশেলসিঙ্ক ঠিক হ'ল, তবে কেন আমাদের নতুন কীওয়ার্ড উল্লেখ করা দরকার?
জুমআইন

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

1
-1 -> এটি মোটেও প্রয়োজন হয় না - আচরণটি একই রকম হবে। একটি নবাগত newসম্পর্কে যা খুব বিভ্রান্তিকর তা মনে হয় তবে আমি মনে করি এটি কেবল আধ্যাত্মিক পাঠযোগ্যতার জন্যই রয়েছে - সংকলকটি আপনাকে কেবল সতর্ক করে দিচ্ছে যে আপনি যখন বেস হিসাবে একই নামের উত্পন্ন শ্রেণি পদ্ধতিটি কল করবেন তখন আপনি বেস শ্রেণীর পদ্ধতিটি পাবেন না যা আপনি করতে পারেন ভাবুন .... এটা উদ্ভট ... খাঁটিভাবে পঠনযোগ্যতার জন্য?
ডন চ্যাডল

1
সম্পূর্ণতার জন্য: যদি এ এবং বি শ্রেণি উভয়ই একটি ইন্টারফেস IMyInterfaceবাস্তবায়িত করে তবে ডেরাইভড শ্রেণীর প্রয়োগ বাস্তবায়ন বলা হবে। এইভাবে IMyInterface c = new B()বি শ্রেণীর বাস্তবায়ন কল করবে। যদি কেবল একটি শ্রেণি ইন্টারফেস প্রয়োগ করে তবে শ্রেণি থেকে যে পদ্ধতিটি এটি প্রয়োগ করে, তাকে কল করা হবে।
নুলিয়াস

61

না, এটি আসলে "নতুন" নয় (শ্লেষকে ক্ষমা করুন)। এটি মূলত একটি পদ্ধতি "লুকানোর" জন্য ব্যবহৃত হয়। অর্থাৎ,

public class Base
{
   public virtual void Method(){}
}

public class Derived : Base
{
   public new void Method(){}
}

আপনি যদি এটি করেন তবে:

Base b = new Derived();
b.Method();

বেসের পদ্ধতিটি হ'ল একটিকে বলা হবে, প্রাপ্ত উত্পন্নর মতো নয়।

আরও কিছু তথ্য: http://www.akadia.com/services/dotnet_polymorphism.html

আপনার সম্পাদনাটি পুনরায় করুন: আমি যে উদাহরণ দিয়েছি, আপনি যদি "নতুন" ব্যবহারের পরিবর্তে "ওভাররাইড" করতে চান তবে আপনি যখন বি.মথোদকে () কল করবেন; পলিমারফিজমের কারণে ডারাইভড ক্লাসের পদ্ধতিটি ডাকা হত।


পাবলিক ক্লাস বেস {পাবলিক ভার্চুয়াল শূন্য পদ্ধতি () so কনসোল.উরাইটলাইন ("বেস"); }} পাবলিক ক্লাস ডারাইভড: বেস {পাবলিক শূন্য পদ্ধতি () so কনসোল.উরাইটলাইন ("উত্পন্ন"); }} বেস বি = নতুন উত্পন্ন (); b.Method (); আমি "বেস" পেয়েছি .. যদি আমি উত্পন্ন ক্লাসে "নতুন" যুক্ত করি তবে আমি এখনও "বেস" পাই ..
মাইকেল সিঙ্ক

@ মাইকেলটি পদ্ধতিটি এখনও ভার্চুয়াল
রুন এফএস

@ মিশেলসিঙ্ক: আপনাকে সেই কোডটি সহ একটি সতর্কতা দেখানো উচিত; সতর্কতা ডেরাইভড.মথোদ () 'উত্তরাধিকার সূত্রে প্রাপ্ত সদস্য' বেস.মথোদ () 'কে লুকায়। বর্তমান সদস্যকে সেই প্রয়োগকে ওভাররাইড করতে, ওভাররাইড কীওয়ার্ডটি যুক্ত করুন। অন্যথায় নতুন কীওয়ার্ড যুক্ত করুন।
ক্রিস্টোফার ম্যাকআটাকনি

2
@ মিশেলসিঙ্ক যদি "ওভাররাইড" শব্দটি বাদ দেয় তবে ডিফল্ট আচরণটি "নতুন" উদাহরণস্বরূপ, পদ্ধতি লুকানো। সুতরাং আপনি যে শব্দটি নতুন রেখে গেছেন তা কোনও পার্থক্য করে না।
বিফ্রি

1
হ্যাঁ. এটাই আমারও মনে হয়। সি # কেন "নতুন" কীওয়ার্ড যুক্ত করলেন তা নিশ্চিত নন .. এটি কেবল সতর্কতা অদৃশ্য করার জন্য .. স্ট্যাকওভারফ্লো
মাইকেল সিঙ্ক

22

অন্যরা যেমন ব্যাখ্যা করেছে, এটি একটি বিদ্যমান পদ্ধতি লুকানোর জন্য ব্যবহৃত হয়। এটি এমন কোনও পদ্ধতির ওভাররাইডের জন্য কার্যকর যা পিতামাতার ক্লাসে ভার্চুয়াল নয়।

মনে রাখবেন যে "নতুন" সদস্য তৈরি করা বহুকর্মী নয়। যদি আপনি অবজেক্টটি বেস প্রকারে ফেলে দেন তবে এটি উত্পন্ন টাইপের সদস্য ব্যবহার করবে না।

আপনার যদি বেস ক্লাস থাকে:

public class BaseClass
{
    public void DoSomething() { }
}

এবং তারপরে উত্পন্ন শ্রেণি:

public class DerivedType : BaseClass
{
    public new void DoSomething() {}

}

যদি আপনি কোনও প্রকারের ঘোষণা দেন DerivedTypeএবং তারপরে এটি , DoSomething()ালেন তবে পদ্ধতিটি বহুকর্মী নয়, এটি বেস ক্লাসের পদ্ধতিটিকে ডেকেছে, প্রাপ্ত উত্সকে নয়।

BaseClass t = new DerivedType();
t.DoSomething();// Calls the "DoSomething()" method of the base class.

1
এটি বেস ক্লাস থেকে পদ্ধতিটি কল করবে এমনকি আপনি ডেরিভেডটাইপ থেকে "নতুন" সরিয়ে ফেলবেন ..
মাইকেল সিঙ্ক

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

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

কী থেকে লুকিয়ে আছে? এটি অবশ্যই পাওয়া যাবে না যে newউত্সের ধরণ থেকে বেস প্রকারটি আড়াল করে, কারণ আপনি সর্বদা base.<type>স্বরলিপিটি ব্যবহার করে বেস টাইপ অ্যাক্সেস করতে পারবেন না ?
জ্ঞানীগুয়ে

@ থ্যাটাওয়াইজ গুয় এটি "লুকানো" এই অর্থে যে আপনার কোডটিতে উত্পন্ন ক্লাসটি ব্যবহার করার সময় বেস পদ্ধতিটি কল করা হবে না। এটি এখনও অভ্যন্তরীণভাবে ব্যবহার করে বলা যেতে পারে base.<method>এবং আপনি যদি আপনার কোডের বেস টাইপ করেন তবে এটি বাহ্যিকভাবেও বলা যেতে পারে। এটি বেসিক পদ্ধতিটিকে "আড়াল" করার চেয়ে "ওভাররাইডিং" হিসাবে ভাবা আরও প্রযুক্তিগতভাবে সঠিক।
ড্যান হারবার্ট

7

ডক্স থেকে:

যদি উত্পন্ন শ্রেণিতে পদ্ধতিটি নতুন কীওয়ার্ডের আগে থাকে তবে পদ্ধতিটি বেস শ্রেণিতে পদ্ধতি থেকে স্বতন্ত্র হওয়া হিসাবে সংজ্ঞায়িত হয়।

বাস্তবে এর অর্থ কী:

যদি আপনি অন্য শ্রেণীর হয়ে থাকেন এবং আপনার যদি এমন একটি পদ্ধতি থাকে যা একই স্বাক্ষরটি ভাগ করে দেয় তবে আপনি এটিকে 'নতুন' হিসাবে সংজ্ঞায়িত করতে পারেন যাতে এটি অভিভাবক শ্রেণীর থেকে পৃথক। এর অর্থ হ'ল যদি আপনার 'পিতামাতা' শ্রেণীর একটি রেফারেন্স থাকে তবে সেই বাস্তবায়ন কার্যকর করা হবে, আপনার যদি শিশু শ্রেণির একটি রেফারেন্স থাকে তবে সেই বাস্তবায়ন কার্যকর করা হবে।

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

এর জন্য এমএসডিএন- তে প্রচুর তথ্য রয়েছে ।


এই আচরণটি ঘটে যাওয়ার সাথে newসেখানে থাকার কোনও সম্পর্ক নেই। এটি সিনট্যাকটিক / পঠনযোগ্যতা।
ডন চ্যাডল

3

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


3

দীর্ঘ গল্প সংক্ষিপ্ত - এটি প্রয়োজন হয় না, এটি কোনও আচরণ পরিবর্তন করে না, এবং পাঠযোগ্যতার জন্য এটি খাঁটি রয়েছে।

এজন্য ভিএস-তে আপনি কিছুটা স্কুইগলি দেখতে পাবেন, তবুও আপনার কোডটি সংকলন করবে এবং পুরোপুরি সূক্ষ্ম এবং প্রত্যাশার মতো চলবে।

একজনকে ভাবতে হবে যে newকীওয়ার্ডটি তৈরি করা সত্যিই তখন মূল্যবান ছিল যখন তার অর্থ হ'ল বিকাশকারীর স্বীকৃতি হ'ল "হ্যাঁ, আমি জানি আমি একটি বেস পদ্ধতি লুকিয়ে রেখেছি, হ্যাঁ আমি জানি আমি virtualবা overriden(পলিমারফিজম) সম্পর্কিত কিছু করছি না - আমি সত্যিই এটির নিজস্ব পদ্ধতি তৈরি করতে চাই।

এটি আমার কাছে কিছুটা উদ্ভট, তবে সম্ভবত কেবলমাত্র আমি একটি Javaপটভূমি থেকে এসেছি এবং C#উত্তরাধিকারের মধ্যে এই মৌলিক পার্থক্য রয়েছে Java: ইন Java, পদ্ধতিগুলি নির্দিষ্ট না করে পূর্বনির্ধারিতভাবে ভার্চুয়াল final। ইন C#, পদ্ধতিগুলি নির্ধারিত না হলে ডিফল্টরূপে চূড়ান্ত / কংক্রিট হয় virtual


1

এমএসডিএন থেকে :

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


0

এই গোছা সাবধান।
আপনার একটি ইন্টারফেসে একটি পদ্ধতি নির্ধারিত রয়েছে যা বেস ক্লাসে প্রয়োগ করা হয়। তারপরে আপনি একটি উদ্ভূত শ্রেণি তৈরি করেন যা ইন্টারফেসের পদ্ধতিটি আড়াল করে, তবে বিশেষভাবে উদ্ভুত শ্রেণিকে ইন্টারফেসটি বাস্তবায়ন হিসাবে ঘোষণা করবেন না। তারপরে আপনি যদি ইন্টারফেসের রেফারেন্সের মাধ্যমে পদ্ধতিটি কল করেন তবে বেস ক্লাসের পদ্ধতিটি কল করা হবে। তবে আপনার উত্পন্ন শ্রেণিটি যদি বিশেষভাবে ইন্টারফেসটি প্রয়োগ করে তবে তার পদ্ধতিটি যেকোন প্রকারের রেফারেন্স ব্যবহার করা হবে।

interface IMethodToHide
{
    string MethodToHide();
}

class BaseWithMethodToHide : IMethodToHide
{
    public string MethodToHide()
    {
        return "BaseWithMethodToHide";
    }
}

class DerivedNotImplementingInterface   : BaseWithMethodToHide
{
    new public string MethodToHide()
    {
        return "DerivedNotImplementingInterface";
    }
}

class DerivedImplementingInterface : BaseWithMethodToHide, IMethodToHide
{
    new public string MethodToHide()
    {
        return "DerivedImplementingInterface";
    }
}

class Program
{
    static void Main()
    {
        var oNoI = new DerivedNotImplementingInterface();
        IMethodToHide ioNoI = new DerivedNotImplementingInterface();

        Console.WriteLine("reference to the object type DerivedNotImplementingInterface calls the method in the class " 
            + oNoI.MethodToHide());
        // calls DerivedNotImplementingInterface.MethodToHide()
        Console.WriteLine("reference to a DerivedNotImplementingInterface object via the interfce IMethodToHide calls the method in the class " 
            + ioNoI.MethodToHide());
        // calls BaseWithMethodToHide.MethodToHide()
        Console.ReadLine();

        var oI = new DerivedImplementingInterface();
        IMethodToHide ioI = new DerivedImplementingInterface();

        Console.WriteLine("reference to the object type DerivedImplementingInterface calls the method in the class " 
            + oI.MethodToHide());
        // calls DerivedImplementingInterface.MethodToHide()
        Console.WriteLine("reference to a DerivedImplementingInterface object via the interfce IMethodToHide calls the method in the class " 
            + ioI.MethodToHide());
        // calls DerivedImplementingInterface.MethodToHide()
        Console.ReadLine();

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