W którym momencie jest tworzony obiekt-atrybut?

0

Zastanawiam się, w którym momencie jest tworzony obiekt klasy dziedziczącej po System.Attribute?
Musimy stworzyć po raz pierwszy obiekt klasy?
Załadować bibliotekę za pomocą metody Assembly.LoadFrom().., czy też kiedy indziej?

1

Z moich badań wynika że środowisko jak zwykle jest oszczędne (niskopoziomowcy by się obrazili) i robi to dopiero wtedy kiedy naprawdę trzeba. Jako że trudno mi to opisać, napisałem krótki kod demonstrujący:

class TestAttribute : Attribute
{
    public TestAttribute()
    {
        // rzucamy wyjątek gdy ktoś nas tworzy :)
        throw new System.ArgumentException();
    }
}

[Test]
class Asdf
{
    public void Test()
    {
        // jawne pobranie atrybutów
        object[] os = this.GetType().GetCustomAttributes(false);
        foreach (object o in os)
            Console.WriteLine(o);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("jak na razie wszystko fajnie");
        Asdf a = new Asdf();
        Console.WriteLine("teraz też ok, samo stworzenie obiektu nic nie zmienia");
        a.Test();
        Console.WriteLine("bezpośrednie odwołanie do atrybutu, teraz już musi zostać stworzony");
    }
}
0

Nie mogę sobie poradzić z tematem.

Napisałem program, który "bada" (pod prymitywnym kątem) bibliotekę dll.
Najbardziej interesuje mnie w tym momencie zaczytanie atrybutów danych klas.

kod programu:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharedLibrary;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            AsmTest a= new AsmTest();
            Console.Read();
        }
    }

    class AsmTest
    {
        public AsmTest()
        {

            OpenFileDialog opf = new OpenFileDialog();
            opf.ShowDialog();
            Assembly asm = Assembly.LoadFrom(opf.FileName);
            Module[] modules = asm.GetModules();

     
            //Console.WriteLine(.ToString()+" Taht is att type");

            foreach (Module m in modules)
            {
                Console.WriteLine(m.FullyQualifiedName);
            }


            Type[] types = asm.GetTypes();

            foreach (Type t in types)
            {
                
                Console.WriteLine("\nClass name: "+t.FullName+"  "+ t.Namespace);

                //gettin atributes

                TestcaseSettingsKeysAttribute[] atts = (TestcaseSettingsKeysAttribute[])t.GetCustomAttributes(typeof(TestcaseSettingsKeysAttribute), false);
                Console.Write("Atributes count: "+atts.Length);
                foreach (TestcaseSettingsKeysAttribute at in atts)
                {
                    Console.WriteLine("Values, count: " + at.SettingsKeys.Length + "\n");
                    foreach (string val in at.SettingsKeys)
                    {
                        Console.WriteLine(val+" ");
                    }
                    Console.WriteLine("\n");
                }
                Console.WriteLine("\nMethods: ");
                
                MemberInfo[] mi = t.GetMethods();

                foreach (MemberInfo m in mi)
                {
                    Console.WriteLine("Method: " + m.Name);
                }
            }
            
            
        }
    }
}

Biblioteka, którą badam ma postać:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharedLibrary;

namespace Library
{
    interface IExecutable
    {
        int ExecuteTest();
    }

    [Testcase("Core", "1")]
    [TestcaseSettingsKeysAttribute("make", "model", "type", "year")]
    public class Class2:IExecutable
    {
        private void ShowMe()
        {
            MessageBox.Show("Private method of class2");
        }
        public int GetValue()
        {
            return 2;
        }

        public int ExecuteTest()
        {
            Console.WriteLine("Odpalam ExecuteTest!");
            return 1;
        }

    }
   
}

Po odpaleniu programu w konsoli widnieje, Atrributes count 0, mimo zadeklarowanej jednej sztuki.
Ciekawostka, jeśli zamienię w:

TestcaseSettingsKeysAttribute[] atts = (TestcaseSettingsKeysAttribute[])t.GetCustomAttributes(typeof(TestcaseSettingsKeysAttribute), false);
                Console.Write("Atributes count: "+atts.Length);
                foreach (TestcaseSettingsKeysAttribute at in atts)

wszystkie TestcaseSettingsKeysAttribute na Attribute, wykrywa mi 2 atrybuty.

1

Nie podałeś deklaracji TestcaseSettingsKeysAttribute.

Nie napisałeś też o co chodzi, więc muszę zgadywać. Chcesz pobrać atrybuty przypisane do klasy Class2? Robisz to źle.

(TestcaseSettingsKeysAttribute[])t.GetCustomAttributes(typeof(TestcaseSettingsKeysAttribute), false);

Ta linia nie ma żadnego sensu. Pobierasz wszystkie atrybuty z TestcaseSettingsKeysAttribute po czym rzutujesz je na tablicę TestcaseSettingsKeysAttribute.

Jeśli chcesz pobrać atrybuty z Class2 to napisz:

t.GetCustomAttributes(typeof(TestcaseSettingsKeysAttribute), false);

PS. i korzystaj z dokumentacji.

0
MSM napisał(a)
(TestcaseSettingsKeysAttribute[])t.GetCustomAttributes(typeof(TestcaseSettingsKeysAttribute), false);

Ta linia nie ma żadnego sensu. Pobierasz wszystkie atrybuty z TestcaseSettingsKeysAttribute po czym rzutujesz je na tablicę TestcaseSettingsKeysAttribute.

Jeśli chcesz pobrać atrybuty z Class2 to napisz:

t.GetCustomAttributes(typeof(TestcaseSettingsKeysAttribute), false);

Ale czym różni się pierwszy kod od drugiego?
GetCustomAttributes zwraca tablice obiektów, dlaczego nie może rzutować jej na tablice TestcaseSettingsKeys, skoro w metodzie tego sobie zażyczył i wie że elementy tego typu zostaną zwrócone.

Poza tym, to można wymusić tworzenie atrybutów przed stworzeniem obiektu klasy do ktorej przypisane są atrybuty - jesli jest taka konieczność.

1

Ups, pomyłka ;) Miało być

t.GetCustomAttributes(typeof(Class2), false);
(domyślam się że autorowi chodziło o pobranie atrybutów z klasy Class2 w bibliotece.)

Tak to jest jak się kopiuje kod...

0
MSM napisał(a)

Ups, pomyłka ;) Miało być

t.GetCustomAttributes(typeof(Class2), false);
(domyślam się że autorowi chodziło o pobranie atrybutów z klasy Class2 w bibliotece.)

Tak to jest jak się kopiuje kod...

Skoro t to jest obiekt klasy Class2 to po co wywoływać na jego rzecz metodę wyszukującą atrybuty tej klasy?
Może i masz rację, nie wiem ;p

ja użyłem tak:

foreach (Attribute att in t.GetCustomAttributes(true)){...}
i sobie biegam po atrybutach klasy ;p

1 użytkowników online, w tym zalogowanych: 0, gości: 1