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?
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");
}
}
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.
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.
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ść.
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...
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