সি # - এক তালিকায় একাধিক জেনেরিক প্রকার


152

এটি সম্ভবত সম্ভব নয় তবে আমার এই ক্লাসটি রয়েছে:

public class Metadata<DataType> where DataType : struct
{
    private DataType mDataType;
}

এর আরও অনেক কিছু আছে তবে আসুন এটি সহজ রাখি। জেনেরিক টাইপ (ডেটা টাইপ) যেখানে স্টেটমেন্ট অনুসারে মান প্রকারের মধ্যে সীমাবদ্ধ। আমি যা করতে চাই তা হ'ল বিভিন্ন ধরণের (ডেটা টাইপ) এই মেটাডেটা অবজেক্টগুলির একটি তালিকা। যেমন:

List<Metadata> metadataObjects;
metadataObjects.Add(new Metadata<int>());
metadataObjects.Add(new Metadata<bool>());
metadataObjects.Add(new Metadata<double>());

এটা কি সম্ভব?


24
আমি ভাবছি যদি কেবল একটি ব্যবহারের তুলনায় নীচের উত্তরগুলিতে পদ্ধতির কোনও বাস্তব সুবিধা রয়েছে List<object>? তারা বক্সিং / আনবক্সিং বন্ধ করবে না, তারা ingালাইয়ের প্রয়োজনীয়তা সরিয়ে দেবে না এবং শেষ পর্যন্ত আপনি এমন একটি Metadataবস্তু পেয়ে যা যা আপনাকে প্রকৃত সম্পর্কে কিছু না বলে DataType, আমি এই সমস্যাগুলি সমাধান করার সমাধান খুঁজছিলাম। আপনি যদি কোনও ইন্টারফেস / শ্রেণি ঘোষণা করতে চলেছেন, কেবল প্রয়োগকারী / উত্পন্ন জেনেরিক প্রকারটিকে জেনেরিক তালিকায় রাখতে সক্ষম হবেন, অর্থহীন স্তর ব্যতীত অন্যটি ব্যবহার করা ছাড়া এটি কতটা আলাদাList<object> ?
সায়েব আমিনী

9
বিমূর্ত বেস শ্রেণি এবং ইন্টারফেস উভয়ই তালিকায় যুক্ত হতে পারে এমন উপাদানগুলির সীমাবদ্ধ করে নিয়ন্ত্রণের একটি ডিগ্রি সরবরাহ করে। এতে বক্সিং কীভাবে আসে তাও আমি দেখতে পাচ্ছি না।
0b101010

3
অবশ্যই, আপনি যদি .NET v4.0 বা উচ্চতর ব্যবহার করে থাকেন তবে সম্মতি হ'ল সমাধান। List<Metadata<object>>কৌতুক করে
0b101010

2
@ 0b101010 আমি একই চিন্তা করছিলাম, তবে দুর্ভাগ্যক্রমে মানের ধরণের ক্ষেত্রে পরিবর্তনের অনুমতি নেই allowed ওপিতে যেহেতু structবাধা রয়েছে তাই এটি এখানে কাজ করে না। দেখুন
নওফাল

@ 0b101010, উভয়ই কেবলমাত্র রেফারেন্স প্রকারকে সীমাবদ্ধ করে, কোনও বিল্ট-ইন মান ধরণের এবং যে কোনও স্ট্রাক্ট এখনও যুক্ত করা যায়। এছাড়াও, শেষে, আপনার MetaDataপ্রতিটি মৌলের অন্তর্নিহিত মান ধরণের সম্পর্কে কোনও (সংকলন সময়) তথ্য না দিয়ে আপনার মূল মানের প্রকারের পরিবর্তে রেফারেন্স প্রকারের একটি তালিকা রয়েছে , এটি কার্যকরভাবে "বক্সিং"।
সায়েব আমিনী

উত্তর:


195
public abstract class Metadata
{
}

// extend abstract Metadata class
public class Metadata<DataType> : Metadata where DataType : struct
{
    private DataType mDataType;
}

5
কি দারুন! আমি সত্যিই তা সম্ভব বলে মনে করি না! তুমি জীবন রক্ষাকারী মানুষ!
কার্ল

2
এই জন্য +10! আমি জানি না কেন এটি সংকলন করছে .. ঠিক আমার যা প্রয়োজন!
ওডিস 20'11

আমারও একই সমস্যা রয়েছে, তবে আমার জেনেরিক ক্লাসটি অন্য জেনেরিক ক্লাস থেকে প্রসারিত, তাই আমি আপনার সমাধানটি ব্যবহার করতে পারি না ... এই পরিস্থিতির সমাধানের জন্য কোনও ধারণা?
শেরিডান

10
একটি সহজ তুলনায় এই পদ্ধতির কোন সুবিধা আছে List<object>? ওপির প্রশ্নের অধীনে পোস্ট করা আমার মন্তব্যটি দেখুন।
সায়েব আমিনী

10
@ সায়েবমিনি একটি তালিকা <ওয়েবসাইট> কোনও বিকাশকারীকে কোনও অভিপ্রায় দেখায় না, বা এটি কোনও বিকাশকারীকে ভুল করে তালিকায় কোনও মেটাডেটা-র অবজেক্ট যুক্ত করে পায়ে গুলি করতে বাধা দেয় না। একটি তালিকা <মেটাডাটা> ব্যবহার করে বোঝা যাচ্ছে তালিকায় কী থাকা উচিত। সম্ভবত মেটাডাটাতে এমন কিছু সরকারী সম্পত্তি / পদ্ধতি থাকবে যা উপরের উদাহরণগুলিতে দেখানো হয়নি। অবজেক্টের মাধ্যমে এগুলি অ্যাক্সেস করার জন্য একটি জটিল castালাই প্রয়োজন।
বাজে

92

লেপির উত্তর অনুসরণ করে, কেন MetaDataএকটি ইন্টারফেস তৈরি করবেন না :

public interface IMetaData { }

public class Metadata<DataType> : IMetaData where DataType : struct
{
    private DataType mDataType;
}

কেউ আমাকে বলতে পারেন কেন এই পদ্ধতিটি আরও ভাল?
Lazlo

34
যেহেতু কোনও সাধারণ কার্যকারিতা ভাগ করে নেওয়া হয় না - তবে কেন তখন একটি বেস ক্লাস নষ্ট করবেন? একটি ইন্টারফেস যথেষ্ট
flq

2
কারণ আপনি স্ট্রাকটে ইন্টারফেস প্রয়োগ করতে পারেন।
ড্যামিয়ান লেজস্কিওস্কি - ভ্যাশ

2
ভার্চুয়াল পদ্ধতি ব্যবহার করে শ্রেণীর উত্তরাধিকার ইন্টারফেস পদ্ধতির তুলনায় প্রায় 1.4x দ্রুত x সুতরাং আপনি যদি মেটাডেটা <ডেটাটাইপ> তে কোনও অ-জেনেরিক মেটাডেটা (ভার্চুয়াল) পদ্ধতি / বৈশিষ্ট্যগুলি প্রয়োগ করার পরিকল্পনা করেন, পারফরম্যান্স যদি উদ্বেগজনক হয় তবে ইন্টারফেসের পরিবর্তে একটি বিমূর্ত শ্রেণি চয়ন করুন। অন্যথায়, একটি ইন্টারফেস ব্যবহার করা আরও নমনীয় হতে পারে।
TamusJRoyce

30

আমি newকীওয়ার্ডটি ব্যবহার করে একটি অ-জেনেরিক সংস্করণও ব্যবহার করেছি :

public interface IMetadata
{
    Type DataType { get; }

    object Data { get; }
}

public interface IMetadata<TData> : IMetadata
{
    new TData Data { get; }
}

উভয় Dataসদস্যকে অনুমতি দেওয়ার জন্য স্পষ্টত ইন্টারফেস প্রয়োগ করা হয় :

public class Metadata<TData> : IMetadata<TData>
{
    public Metadata(TData data)
    {
       Data = data;
    }

    public Type DataType
    {
        get { return typeof(TData); }
    }

    object IMetadata.Data
    {
        get { return Data; }
    }

    public TData Data { get; private set; }
}

আপনি কোনও সংস্করণ লক্ষ্যবস্তু মানের ধরণ পেতে পারেন:

public interface IValueTypeMetadata : IMetadata
{

}

public interface IValueTypeMetadata<TData> : IMetadata<TData>, IValueTypeMetadata where TData : struct
{

}

public class ValueTypeMetadata<TData> : Metadata<TData>, IValueTypeMetadata<TData> where TData : struct
{
    public ValueTypeMetadata(TData data) : base(data)
    {}
}

এটি যেকোন ধরণের জেনেরিক সীমাবদ্ধতায় প্রসারিত হতে পারে।


4
আপনি যেভাবে এটি ব্যবহার করবেন ( DataTypeএবং object Dataঅনেক সাহায্য করেছেন) তা দেখিয়েছেন কেবলমাত্র +1
ওডিস

4
আমি উদাহরণস্বরূপ লিখতে সক্ষম হবে বলে মনে হচ্ছে না Deserialize<metadata.DataType>(metadata.Data);। এটি আমাকে বলে যে প্রতীক মেটাডেটা সমাধান করতে পারে না । জেনেরিক পদ্ধতির জন্য এটি ব্যবহার করার জন্য কীভাবে ডেটা টাইপ পুনরুদ্ধার করবেন?
Cœur
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.