প্রতিবিম্বের মাধ্যমে একটি নেমস্পেসে সমস্ত প্রকার পাওয়া


268

আপনি কীভাবে সি # তে প্রতিবিম্বের মাধ্যমে একটি নেমস্পেসে সমস্ত ক্লাস পাবেন?


আপনি কি আপনার প্রশ্নটি সম্পাদনা করতে পারবেন ... সাবটেক্সট প্রশ্নটি 'সি # নামের
জায়গার

আপনি এখানে দেখতে পারেন । এখানে 2 টি বিভিন্ন নমুনা রয়েছে।
ফাতেহ গার্ডাল

উত্তর:


316

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

string nspace = "...";

var q = from t in Assembly.GetExecutingAssembly().GetTypes()
        where t.IsClass && t.Namespace == nspace
        select t;
q.ToList().ForEach(t => Console.WriteLine(t.Name));

83

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

AppDomain.CurrentDomain.GetAssemblies()
                       .SelectMany(t => t.GetTypes())
                       .Where(t => t.IsClass && t.Namespace == @namespace)

আপনি অন্যান্য ডোমেনের ক্লাস না চাইলে এটি কাজ করা উচিত। সমস্ত ডোমেনের একটি তালিকা পেতে, এই লিঙ্কটি অনুসরণ করুন।


1
ভাল কাজ করে - একটি ছোট্ট অনুস্মারক: আমি " && t.Namespace == @namespace" অপসারণ করার চেষ্টা করেছি - যা আমাকে সমস্ত উপহার দিয়েছে। নেট সমাবেশগুলি :-)
নেটসেই 1964

@ Netsi1964 যদি আপনি সরাতে && t.Namespace == @namespaceআপনি সব পেতে শ্রেণীর এর সব সমাহারগুলি .net এর সহ। GetAssembliesআপনাকে সমস্ত সমাবেশ GetAssemblies().SelectMany(t => t.GetTypes())দেবে এবং সমস্ত সমাবেশ থেকে সমস্ত ধরণের (শ্রেণি, স্ট্রাক্ট ইত্যাদি) দেবে।
নওফাল

আমি ডটনেট কোর ২.২ এ উন্নীত করেছি (২.১ থেকে) এবং এই কোডটি আমার নির্দিষ্ট সমাবেশের জন্য কাজ করা বন্ধ করে দিয়েছে। আমি যে সমাবেশটি চেয়েছিলাম সেটি কোডের কোথাও রেফারেন্স করা হয়নি তাই লোড হয়নি! ২.১ এ এটি লোড করা হয়েছিল, তবে ২.২ এর অলস লোডিং আছে বলে মনে হচ্ছে?
হার্ভে

@ হার্ভে .NET কোর এর সাথে শুরু করার জন্য অ্যাপডোমেন আছে?
নওফাল

@ নওফাল হ্যাঁ এই কোডটি আগে 2.1 তে কাজ করেছিল। আমি দেখতে পেয়েছি যে আমি Assembly.Load(nameof(NameOfMyNamespace))ঠিকঠাক কাজ করে কোনও অ্যাসেম্বলি লোড করতে বাধ্য করি ।
হার্ভে

28
using System.Reflection;
using System.Collections.Generic;
//...

static List<string> GetClasses(string nameSpace)
{
    Assembly asm = Assembly.GetExecutingAssembly();

    List<string> namespacelist = new List<string>();
    List<string> classlist = new List<string>();

    foreach (Type type in asm.GetTypes())
    {
        if (type.Namespace == nameSpace)
            namespacelist.Add(type.Name);
    }

    foreach (string classname in namespacelist)
        classlist.Add(classname);

    return classlist;
}

নোট: উপরের কোডটি কী চলছে তা চিত্রিত করে। আপনি যদি এটি বাস্তবায়ন করেন তবে একটি সরলীকৃত সংস্করণ ব্যবহার করা যেতে পারে:

using System.Linq;
using System.Reflection;
using System.Collections.Generic;
//...

static IEnumerable<string> GetClasses(string nameSpace)
{
    Assembly asm = Assembly.GetExecutingAssembly();
    return asm.GetTypes()
        .Where(type => type.Namespace == nameSpace)
        .Select(type => type.Name);
}

9
আমি বোঝানোর চেষ্টা করছি না, তবে এই কোডটিতে পাওয়া সমস্ত আইটেমের মাধ্যমে একটি সম্পূর্ণ অপ্রয়োজনীয় তালিকা এবং পুনরাবৃত্তি রয়েছে; "নেমস্পেসলিস্ট" এর মাধ্যমে "
শ্রেণিবদ্ধ

10
@ দ্য এক্সেনোসাইড কোড কোডের নমুনার উদ্দেশ্য সর্বদা কোড লেখার "সেরা" উপায় দেখানোর জন্য বোঝানো হয় না, তবে কীভাবে কী হয় তা স্পষ্টভাবে জানাতে হয়।
রায়ান ফারলে

4
আমি কেবল শিক্ষার স্বার্থে এটি দেখিয়েছিলাম; বোঝার উপর lyণাত্মকভাবে প্রভাবিত করে এমন একটি খারাপ উদাহরণ ঝুঁকি না দিয়ে বস্তুগত মানুষকে সর্বোত্তম উদাহরণ থেকে শেখার আমাদের দায়িত্ব। আমি এটি বিশেষত ক্ষতিকারক হিসাবে বলছি না, তবে আমি অনুভূতির সাথে একমত
নই

4
আমি যদি একটি প্রশ্নের উত্তর জিজ্ঞাসা করা হয় যদি এটি দরকারী না হয় তবে আমি নীচে ভোট দিয়েছি। উপরের / নীচে ভোট বোতামের উপরে ঘোরাফেরা করার সময় আপনি যে ইঙ্গিতটি দেখেন তা বলে "এটি সহায়ক ছিল"। আমার কাছে একটি উত্তর উপরে / নিচে ভোট দেওয়ার সিদ্ধান্তটি হ'ল এটি জিজ্ঞাসিত প্রশ্নের উত্তর দেওয়ার ক্ষেত্রে সহায়ক ছিল কি না is
রায়ান ফারলে 16

3
দুটি তালিকা এবং দুটি পুনরাবৃত্তির সাহায্যে আপনি কেবলমাত্র জিনিসটি হ'ল আপনি দুটি তালিকা কেন ব্যবহার classlistকরেছেন এবং asm.GetTypes()ফলাফলের উপরে প্রথম পুনরাবৃত্তিতে সরাসরি যুক্ত করেননি কেবল তা বের করার চেষ্টা করে আমাকে ধীর করে দেওয়া হয়েছিল।
অধ্যাপক

20

একটি নির্দিষ্ট সমাবেশ, নেমস্পেস এবং ক্লাসনেমের জন্য:

var assemblyName = "Some.Assembly.Name"
var nameSpace = "Some.Namespace.Name";
var className = "ClassNameFilter";

var asm = Assembly.Load(assemblyName);
var classes = asm.GetTypes().Where(p =>
     p.Namespace == nameSpace &&
     p.Name.Contains(className) 
).ToList();

দ্রষ্টব্য: প্রকল্পটি অবশ্যই সমাবেশটি উল্লেখ করবে


12

এখানে লোডারঅ্যাক্সপশন ত্রুটিগুলির জন্য একটি স্থিরতা আপনি খুঁজে পেতে পারেন সম্ভবত কোনও ধরণের একটি অন্য সমাবেশে টাইপ করে তবে:

// Setup event handler to resolve assemblies
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);

Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();
// process types here

// method later in the class:
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
    return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}

এটি অন্যান্য অ্যাসেমব্লিতে সংজ্ঞায়িত লোডিং প্রকারের সাথে সহায়তা করবে।

আশা করি এইটি কাজ করবে!


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

যদিও আপনি কিছুক্ষণের জন্য আমাকে বিভ্রান্ত করেছেন। আমি এখনও অনুমান করতে পারি যে স্টাফগুলি Assembly aস্বাভাবিক প্রক্রিয়াজাতকরণের প্রতিনিধিত্ব করে যা এই ইভেন্টটিকে আগুনের কারণ হতে পারে। আমি ত্রুটিগুলির aসাহায্যে কোনও ব্যবহার দেখছি না LoaderException। আমি কি সঠিক?
অধ্যাপক

9

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

Assembly.GetTypes()স্থানীয় সমাবেশে কাজ করে, বা আপনি প্রথমে কোনও সমাবেশ লোড করতে পারেন তারপরে ফোন GetTypes()করতে পারেন।


2
সঠিক উত্তরের জন্য +1। AppDomain.CurrentDomain.GetAssembliesসহায়ক হতে পারে।
নওফাল

... এবং তারপরে লুপ করুন, নামগুলির সাথে মেলে না এমনগুলি ফিল্টার করে।
টিজে ক্রাউডার

ওপি বিশেষত "একটি নেমস্পেসে ক্লাস" চেয়েছিল, যেখানে এটি আপনাকে "একটি সমাবেশে প্রকার" দেয় - সুতরাং এই উত্তরটি অসম্পূর্ণ। সঠিক উত্তরটি সম্ভবত এটি একটি , যা কেবল সমস্ত অ্যাসেম্বলি থেকে ক্লাস গণনা করে।
mindplay.dk

6

ঠিক যেমন @ কাকু উত্তর, তবে এক্সটেনশন পদ্ধতিগুলি ব্যবহার করে:

string @namespace = "...";

var types = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t.IsClass && t.Namespace == @namespace)
    .ToList();

types.ForEach(t => Console.WriteLine(t.Name));

5

মাত্র এক সারিতে নেমস্পেস নামের অংশে সমস্ত ক্লাস পান:

var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();

3

নেমস্পেসগুলি আসলে রানটাইমের ডিজাইনে বরং প্যাসিভ এবং মূলত সাংগঠনিক সরঞ্জাম হিসাবে পরিবেশন করে। .NET- এ টাইপের পুরো নাম নেমস্পেস এবং ক্লাস / এনুম / ইত্যাদি নিয়ে গঠিত। মিলিত। যদি আপনি কেবল একটি নির্দিষ্ট সমাবেশের মধ্য দিয়ে যেতে চান তবে আপনি কেবল সমাবেশ দ্বারা প্রকারভেদগুলি লুপ করবেন। গেট এক্সপোর্টড টাইপস () প্রকারের মান পরীক্ষা করে। নামস্থান । আপনি যদি বর্তমান অ্যাপডোমেনে লোড হওয়া সমস্ত অ্যাসেমব্লির মধ্য দিয়ে যাওয়ার চেষ্টা করছেন তবে এটি অ্যাপডোমাইন.কন্টেনডোমাইন ব্যবহার করে জড়িত। GetAssemblies ()


2
//a simple combined code snippet 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace MustHaveAttributes
{
  class Program
  {
    static void Main ( string[] args )
    {
      Console.WriteLine ( " START " );

      // what is in the assembly
      Assembly a = Assembly.Load ( "MustHaveAttributes" );
      Type[] types = a.GetTypes ();
      foreach (Type t in types)
      {

        Console.WriteLine ( "Type is {0}", t );
      }
      Console.WriteLine (
         "{0} types found", types.Length );

      #region Linq
      //#region Action


      //string @namespace = "MustHaveAttributes";

      //var q = from t in Assembly.GetExecutingAssembly ().GetTypes ()
      //        where t.IsClass && t.Namespace == @namespace
      //        select t;
      //q.ToList ().ForEach ( t => Console.WriteLine ( t.Name ) );


      //#endregion Action  
      #endregion

      Console.ReadLine ();
      Console.WriteLine ( " HIT A KEY TO EXIT " );
      Console.WriteLine ( " END " );
    }
  } //eof Program


  class ClassOne
  {

  } //eof class 

  class ClassTwo
  {

  } //eof class


  [System.AttributeUsage ( System.AttributeTargets.Class |
    System.AttributeTargets.Struct, AllowMultiple = true )]
  public class AttributeClass : System.Attribute
  {

    public string MustHaveDescription { get; set; }
    public string MusHaveVersion { get; set; }


    public AttributeClass ( string mustHaveDescription, string mustHaveVersion )
    {
      MustHaveDescription = mustHaveDescription;
      MusHaveVersion = mustHaveVersion;
    }

  } //eof class 

} //eof namespace 

AttributeClassনাম কী MustHaveAttributesসব? কোনও শ্রেণীর বৈশিষ্ট্য আছে কি না তা পরীক্ষার সাথে সম্পর্কিত আমি কিছুই দেখছি না। এটি সহায়তার চেয়ে বিভ্রান্তিকর।
অধ্যাপক

1

খুবই সাধারণ

Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}

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