বেনাম শ্রেণি ইন্টারফেস প্রয়োগ করতে পারে?


462

কোনও বেনামি ধরণের একটি ইন্টারফেস প্রয়োগ করা সম্ভব?

আমি একটি কোডের টুকরো পেয়েছি যা আমি কাজ করতে চাই, তবে কীভাবে এটি করতে হয় তা জানি না।

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

public interface DummyInterface
{
    string A { get; }
    string B { get; }
}

public class DummySource
{
    public string A { get; set; }
    public string C { get; set; }
    public string D { get; set; }
}

public class Test
{
    public void WillThisWork()
    {
        var source = new DummySource[0];
        var values = from value in source
                     select new
                     {
                         A = value.A,
                         B = value.C + "_" + value.D
                     };

        DoSomethingWithDummyInterface(values);

    }

    public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

আমি একটি নিবন্ধ ডায়নামিক ইন্টারফেস মোড়ানো পেয়েছি যা একটি পদ্ধতির বর্ণনা করে। এটি কি এটি করার সর্বোত্তম উপায়?


1
লিঙ্কটি পুরানো হয়ে গেছে, এটি সম্ভবত একটি উপযুক্ত বিকল্প liensberger.it/web/blog/?p=298
ফিল কুপার

1
হ্যাঁ, আপনি ব্যবহার .NET 4 এবং উচ্চতর (DLR মাধ্যমে) সঙ্গে এই কাজ করতে পারেন, ImpromptuInterface nuget প্যাকেজ।
BrainSlugs83

1
@ ফিলকুপার আপনার লিঙ্কটি সম্ভবত কমপক্ষে ২০১ 2016 সাল থেকে বন্ধ রয়েছে - তবে ভাগ্যক্রমে এটি এর আগে সংরক্ষণাগারভুক্ত হয়েছিল। web.archive.org/web/20111105150920/http://www.liensberger.it/…
পল

উত্তর:


360

না, বেনামে প্রকারভেদগুলি একটি ইন্টারফেস প্রয়োগ করতে পারে না। থেকে C # এর প্রোগ্রামিং নির্দেশিকা :

নামবিহীন প্রকারগুলি শ্রেণীর ধরণ যা এক বা একাধিক পাবলিক পঠনযোগ্য বৈশিষ্ট্য নিয়ে গঠিত। অন্য ধরণের শ্রেণি সদস্য যেমন পদ্ধতি বা ইভেন্টগুলির অনুমতি নেই। কোনও বেনামি প্রকারটি কোনও ইন্টারফেসে বা বস্তু বাদে টাইপ করা যাবে না।


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

18
@ আরসেনজাহারে: ল্যাম্বদা এক্সপ্রেশনগুলি ভালভাবে ব্যবহার করা হলে কোডের পাঠযোগ্যতা বাড়ায় increase ফাংশনাল চেইনে ব্যবহৃত হলে এগুলি বিশেষত শক্তিশালী হয়, যা স্থানীয় ভেরিয়েবলের প্রয়োজনীয়তা হ্রাস বা নির্মূল করতে পারে।
রায় টিঙ্কার

2
আপনি এইভাবে কৌতুকটি করতে পারেন "বেনামে বাস্তবায়ন ক্লাস - সি এর জন্য একটি নকশার প্যাটার্ন" - twistedoakstudios.com/blog/…
দিমিত্রি পাভলভ

3
@ দিমিত্রিপাভলভ, এটি আশ্চর্যজনকভাবে মূল্যবান ছিল। পথচারীরা: এখানে কনডেন্সড সংস্করণ।
kdbanman

1
আপনি একই ক্ষেত্রের সাথে একটি বেনামী বস্তু বেনামী টাইপ কাস্ট করতে পারেন stackoverflow.com/questions/1409734/cast-to-anonymous-type
Zinov

89

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

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


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

16
@ গুডোর আমি সম্মত হই যে অন্যান্য প্রোগ্রামারদের পক্ষে প্রকল্পটি পাওয়া এবং প্রচুর পরিমাণে অসুবিধা ছাড়াই সংকলন করা সহজ হওয়া উচিত, তবে পোস্টার্পের মতো সরঞ্জামাদি বা ফ্রেমওয়ার্কগুলি এড়ানো এড়ানো পৃথক পৃথকভাবে সম্বোধনযোগ্য issue আপনি যে একই যুক্তিটি করেন তা ভিএস নিজেই বা অন্য কোনও মানহীন এমএস ফ্রেমওয়ার্কের বিরুদ্ধেও তৈরি করা যেতে পারে যা সি # স্পপের অংশ নয়। আপনার এই জিনিসগুলির প্রয়োজন হয় অন্যথায় এটি "পপ যায়"। এটি কোনও সমস্যা নয় আইএমও। সমস্যাটি হ'ল বিল্ডটি এত জটিল হয়ে ওঠে যে সমস্ত জিনিসগুলি একসাথে কাজ করা ঠিকঠাক হয়ে পড়ে।
অ্যারোনএলএস

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

3
এটি এখন অনেক সহজ; কোড উত্পন্ন হওয়ার পরে আইএল সংশোধন করার দরকার নেই; শুধু ImpromptuInterface ব্যবহার করুন । - এটি আপনাকে যে কোনও অবজেক্টকে (বেনামে টাইপ করা অবজেক্টগুলি সহ) কোনও ইন্টারফেসের সাথে আবদ্ধ করতে দেয় (অবশ্যই আপনি যদি ইন্টারফেসের কোনও অংশ ব্যবহার করতে চেষ্টা করেন যা ক্লাসটি আসলে সমর্থন করে না)।
BrainSlugs83

44

ইন্টারফেসে বেনামি ধরণের কাস্টিং এমন কিছু ছিল যা আমি কিছু সময়ের জন্য চেয়েছিলাম তবে দুর্ভাগ্যক্রমে বর্তমান বাস্তবায়ন আপনাকে সেই ইন্টারফেসটির একটি প্রয়োগ করতে বাধ্য করে।

এর চারপাশের সেরা সমাধানটিতে এমন এক ধরণের ডায়নামিক প্রক্সি রয়েছে যা আপনার জন্য বাস্তবায়ন তৈরি করে। দুর্দান্ত লিনফু প্রকল্প ব্যবহার করে আপনি প্রতিস্থাপন করতে পারেন

select new
{
  A = value.A,
  B = value.C + "_" + value.D
};

সঙ্গে

 select new DynamicObject(new
 {
   A = value.A,
   B = value.C + "_" + value.D
 }).CreateDuck<DummyInterface>();

17
ইমপ্রম্প্টু-ইন্টারফেস প্রকল্প এটি DLR ব্যবহার করে .NET 4.0 এ করবে এবং তারপরে লিনফু হালকা হবে।
jbtule

কি DynamicObjectএকটি LinFu ধরনের? System.Dynamic.DynamicObjectকেবলমাত্র একটি সুরক্ষিত কনস্ট্রাক্টর রয়েছে (কমপক্ষে .NET 4.5 এ)।
jdmcnair

হ্যাঁ. আমি লিনফু প্রয়োগের কথা উল্লেখ করছিলাম DynamicObjectযার ডিএলআর সংস্করণটির পূর্বাভাস দেয়
আর্ন ক্ল্যাসেন

14

বেনামি প্রকারগুলি গতিশীল প্রক্সি মাধ্যমে ইন্টারফেস প্রয়োগ করতে পারে।

এই দৃশ্যের সমর্থনে আমি গিটহাব এবং একটি ব্লগ পোস্ট http://wblo.gs/feE এ একটি এক্সটেনশন পদ্ধতি লিখেছি ।

পদ্ধতিটি এভাবে ব্যবহার করা যেতে পারে:

class Program
{
    static void Main(string[] args)
    {
        var developer = new { Name = "Jason Bowers" };

        PrintDeveloperName(developer.DuckCast<IDeveloper>());

        Console.ReadKey();
    }

    private static void PrintDeveloperName(IDeveloper developer)
    {
        Console.WriteLine(developer.Name);
    }
}

public interface IDeveloper
{
    string Name { get; }
}

13

না; কয়েকটি বৈশিষ্ট্য ব্যতীত বেনামে কিছু করা যায় না। আপনার নিজের ধরণের তৈরি করতে হবে। আমি লিঙ্কযুক্ত নিবন্ধটি গভীরভাবে পড়িনি, তবে দেখে মনে হচ্ছে এটি প্রতিবিম্ব ব্যবহার করে। তবে আপনি যদি সি # এর মধ্যে জিনিসগুলির মধ্যে আলোচনাকে সীমাবদ্ধ করেন তবে আপনি যা চান তা করতে পারবেন না।


এবং লক্ষণীয় গুরুত্বপূর্ণ: বৈশিষ্ট্যগুলিতে ফাংশন বা ভয়েডস (অ্যাকশন) এর পাশাপাশি অন্তর্ভুক্ত থাকতে পারে: নতুন নির্বাচন করুন My ... মাই ফাংশন = নতুন ফানক <স্ট্রিং, বুল> (গুলি = মান) = == গুলি)} কাজ করে যদিও আপনি উল্লেখ করতে পারেন না আপনার ফাংশনে নতুন বৈশিষ্ট্য (আমরা "মান" এর পরিবর্তে "এ" ব্যবহার করতে পারি না)।
cfeduke

2
ঠিক আছে, এটি কি কেবল একটি সম্পত্তি যা প্রতিনিধি হিসাবে ঘটে? এটি আসলে কোনও পদ্ধতি নয়।
মার্ক গ্র্যাভেল

1
আমি প্রতিচ্ছবি ব্যবহার করেছি run রানটাইমের সময় প্রকারগুলি তৈরি করতে শিখুন তবে বিশ্বাস করুন এখন রানটাইমের ব্যয় এড়াতে আমি কোনও এওপি সমাধান পছন্দ করব।
নরম্যান এইচ

11

সর্বোত্তম সমাধান হ'ল বেনাম ক্লাস ব্যবহার না করা।

public class Test
{
    class DummyInterfaceImplementor : IDummyInterface
    {
        public string A { get; set; }
        public string B { get; set; }
    }

    public void WillThisWork()
    {
        var source = new DummySource[0];
        var values = from value in source
                     select new DummyInterfaceImplementor()
                     {
                         A = value.A,
                         B = value.C + "_" + value.D
                     };

        DoSomethingWithDummyInterface(values.Cast<IDummyInterface>());

    }

    public void DoSomethingWithDummyInterface(IEnumerable<IDummyInterface> values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

নোট করুন যে আপনাকে ইন্টারফেসের ধরণের কাছে ক্যোয়ারির ফলাফল কাস্ট করতে হবে। এটি করার আরও ভাল উপায় হতে পারে তবে আমি এটি খুঁজে পেলাম না।


2
আপনি values.OfType<IDummyInterface>()castালাইয়ের পরিবর্তে ব্যবহার করতে পারেন । এটি কেবলমাত্র আপনার সংগ্রহে থাকা অবজেক্টগুলিকে ফেরত দেয় যা প্রকৃতপক্ষে সেই ধরণের হয়ে যেতে পারে। এটি সব আপনি কী চান তার উপর নির্ভর করে।
ক্রিস্টোফার এল

7

বিশেষভাবে জিজ্ঞাসিত প্রশ্নের উত্তরটি হ'ল না। তবে আপনি কি উপহাসের ফ্রেমওয়ার্কের দিকে নজর রেখেছেন? আমি এমওকিউ ব্যবহার করি তবে তাদের মিলিয়ন মিলিয়ন রয়েছে এবং তারা আপনাকে লাইনটিতে আংশিক (আংশিক বা সম্পূর্ণ) ইন্টারফেস প্রয়োগ করতে দেয়। যেমন।

public void ThisWillWork()
{
    var source = new DummySource[0];
    var mock = new Mock<DummyInterface>();

    mock.SetupProperty(m => m.A, source.Select(s => s.A));
    mock.SetupProperty(m => m.B, source.Select(s => s.C + "_" + s.D));

    DoSomethingWithDummyInterface(mock.Object);
}

0

আরেকটি বিকল্প হ'ল একটি একক, কংক্রিট প্রয়োগকারী শ্রেণি তৈরি করা যা কনস্ট্রাক্টরে ল্যাম্বডাস নেয়।

public interface DummyInterface
{
    string A { get; }
    string B { get; }
}

// "Generic" implementing class
public class Dummy : DummyInterface
{
    private readonly Func<string> _getA;
    private readonly Func<string> _getB;

    public Dummy(Func<string> getA, Func<string> getB)
    {
        _getA = getA;
        _getB = getB;
    }

    public string A => _getA();

    public string B => _getB();
}

public class DummySource
{
    public string A { get; set; }
    public string C { get; set; }
    public string D { get; set; }
}

public class Test
{
    public void WillThisWork()
    {
        var source = new DummySource[0];
        var values = from value in source
                     select new Dummy // Syntax changes slightly
                     (
                         getA: () => value.A,
                         getB: () => value.C + "_" + value.D
                     );

        DoSomethingWithDummyInterface(values);

    }

    public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

আপনি যা যা করতে যাচ্ছেন তা সবই যদি রূপান্তরিত DummySourceহয় DummyInterfaceতবে কেবল একটি ক্লাস থাকা সহজ হবে DummySourceযা কনস্ট্রাক্টরে একটি নেয় এবং ইন্টারফেসটি প্রয়োগ করে।

তবে, আপনাকে যদি অনেক ধরণের রূপান্তর করতে DummyInterfaceহয় তবে এটি খুব কম বয়লার প্লেট।

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