napisałem następującą aplikację konsoli do przetestowania właściwości statycznych:Jaki jest najlepszy sposób zdefiniowania właściwości statycznej zdefiniowanej raz w podklasie?
using System;
namespace StaticPropertyTest
{
public abstract class BaseClass
{
public static int MyProperty { get; set; }
}
public class DerivedAlpha : BaseClass
{
}
public class DerivedBeta : BaseClass
{
}
class Program
{
static void Main(string[] args)
{
DerivedBeta.MyProperty = 7;
Console.WriteLine(DerivedAlpha.MyProperty); // outputs 7
}
}
}
Ponieważ ta aplikacja konsola demonstruje właściwość MyProperty
istnieje raz dla wszystkich wystąpień klasy bazowej. Czy istnieje wzorzec do zastosowania, który pozwoliłby mi zdefiniować właściwość statyczną, która będzie miała przypisaną pamięć dla każdego typu podklasy?
Biorąc pod uwagę powyższy przykład, chciałbym wszystkich wystąpień DerivedAlpha
dzielić tę samą właściwość statyczna, a wszystkie instancje DerivedBeta
udostępniania inny instancję obiektu statycznego.
Dlaczego próbuję to zrobić?
Leniwie inicjuję zbiór nazw właściwości klas z pewnymi atrybutami (poprzez odbicie). Nazwy właściwości będą identyczne dla każdej wyprowadzonej instancji klasy, więc wydaje się, że przechowywanie jej w każdej instancji klasy jest marnotrawstwem. Nie mogę uczynić go statycznym w klasie bazowej, ponieważ różne podklasy będą miały różne właściwości.
Nie chcę replikować kodu, który zapełnia kolekcję (poprzez odbicie) w każdej klasie pochodnej. Wiem, że jednym z możliwych rozwiązań jest zdefiniowanie metody zapełniania kolekcji w klasie bazowej i wywołanie jej z każdej klasy pochodnej, ale nie jest to najbardziej eleganckie rozwiązanie.
Update - Przykład tego, co robię
Na życzenie Jona, tutaj jest przykładem tego, co próbuję zrobić. Zasadniczo mogę opcjonalnie dekorować właściwości w moich klasach za pomocą atrybutu [SalesRelationship(SalesRelationshipRule.DoNotInclude)]
(istnieją inne atrybuty, jest to tylko uproszczony przykład).
public class BaseEntity
{
// I want this property to be static but exist once per derived class.
public List<string> PropertiesWithDoNotInclude { get; set; }
public BaseEntity()
{
// Code here will populate PropertiesWithDoNotInclude with
// all properties in class marked with
// SalesRelationshipRule.DoNotInclude.
//
// I want this code to populate this property to run once per
// derived class type, and be stored statically but per class type.
}
}
public class FooEntity : BaseEntity
{
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_A { get; set; }
public int? Property_B { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_C { get; set; }
}
public class BarEntity : BaseEntity
{
public int? Property_D { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_E { get; set; }
public int? Property_F { get; set; }
}
Pożądany końcowy wynik
Dostęp FooEntity.PropertiesWithDoNotInclude
zwraca List<string>
od:
{
"Property_A",
"Property_C"
}
Uzyskiwanie dostępu BarEntity.PropertiesWithDoNotInclude
zwraca List<string>
od:
{
"Property_E"
}
OP określił, że "Nazwy właściwości będą identyczne dla każdej wyprowadzonej instancji klasy" - co sugeruje, że jest to efektywna stała dla każdej klasy, co oznacza, że może to być atrybut, który jest następnie pobierany przez odbicie. Nie, nie zachowuje się dokładnie tak jak własność - ale pozwala określić wartość dla klasy, a następnie pobrać tę wartość ... Teraz mamy więcej informacji w pytaniu, tym bardziej przejrzyste jest to, co OP robi, a słownik z 'Type' na * something * jest prawdopodobnie drogą do zrobienia. –
Czy Twoje rozwiązanie ma wykorzystywać podejście singleton (według typu)? Jeśli tak, to mi się podoba - ale można to zrobić nieco rozszerzając. –
@Jon: oops Brakowało mi słowa kluczowego 'static'. –