Наследование класса индекса.net
Я пытаюсь создать индексный класс для всех моих классов в моем проекте.
например.
класс что угодно:
public class cWhatEver : cBase
{
public string Description { get; set; }
public string Label { get; set; }
public string Name { get; set; }
}
Класс, который наследует класс cBase:
public abstract class cBase : IBase, System.ICloneable
{
private static Int64 _Count;
private Int64 _ID;
[ReadOnly(true)]
public Int64 ID {
get { return _ID; }
}
[ReadOnly(true)]
public Int64 Count {
get { return _Count; }
}
public cBase()
{
cBase._Count += 1;
this._ID = cBase._Count - 1;
}
public object Clone()
{
cBase newClone = (cBase)base.MemberwiseClone();
cBase._Count += 1;
newClone._ID = cBase._Count - 1;
return newClone;
}
protected override void Finalize()
{
_Count -= 1;
}
}
Но когда классы создаются, я всегда получаю количество всех элементов во всех классах, которое наследует cBase, а не количество классов (T) или идентификаторов.
Скажем, у класса независимо от 5 предметов, а у класса независимо_1 есть 10 предметов, тогда число равно 15, а не 5 и 10, а идентификатор также учитывается по всем предметам.
Итак, как мне индексировать это право. Может быть, кто-то может помочь мне с этим.
Спасибо
2 ответа
Если я правильно понимаю, вы хотите поддерживать количество экземпляров каждого класса в иерархии. Проблема в том, что _Count
поле является общим для всех экземпляров cBase
, в том числе производные классы.
Возможным решением будет воспользоваться тем фактом, что различные реализации универсального класса имеют свои собственные копии статических полей, т. Е. Если у вас есть этот класс:
class Foo<T>
{
private static int _count;
}
затем Foo<int>
а также Foo<string>
не буду делиться своими _count
поле.
Теперь, как применить это к вашей проблеме? Что ж, есть известный и довольно странный шаблон, называемый шаблоном Curiously recurring template, который использует дженерики необычным образом (*). Так случилось, что статья в Википедии дает пример, который относится именно к вашей проблеме.
Вы определяете базовый класс следующим образом:
abstract class Base<T> where T : Base<T>
{
private static long _count;
public static long Count { get { return _count; } }
public Base()
{
_count++;
}
}
(обратите внимание, что параметр типа ограничен производным от самого общего типа)
Затем вы можете создать производные классы следующим образом:
class Derived1 : Base<Derived1> { }
class Derived2 : Base<Derived2> { }
Эти классы являются подклассами Base<T>
, но они также имеют разные параметры типа, поэтому они не будут использовать свои статические поля. Если вы делаете это:
var d1 = new[] {new Derived1(), new Derived1(), new Derived1(), new Derived1()};
var d2 = new[] {new Derived2(), new Derived2()};
Console.WriteLine("Derived1: {0}", Derived1.Count);
Console.WriteLine("Derived2: {0}", Derived2.Count);
Вы получаете желаемый результат:
Derived1: 4
Derived2: 2
(*) На самом деле этот шаблон изначально взят из C++ и основан на шаблонах, а не на шаблонах, но он довольно хорошо транслируется в C# и другие языки, которые поддерживают шаблоны.
Почему вы хотите сделать такую вещь, на самом деле мне не известно, но в основном проблема в том, что поле *_count* существует только один раз, а не один счетчик для каждого типа класса, производного от него.
Возможной альтернативой будет использование Dictionary<Type,Int64>
, который содержит один различный счетчик для каждого созданного типа класса, затем увеличивает только соответствующий:
public abstract class cBase : IBase, System.ICloneable
{
private static Dictionary<Type,Int64> _counts;
[ReadOnly(true)]
public Int64 Count
{
get { return _counts[this.GetType()]; }
}
public cBase()
{
if(this._counts.Contains(this.GetType())
this._counts[this.GetType()] = this._counts[this.GetType()] +1;
else
this._counts.Add(this.GetType(),1);
this._ID = this._count[this.GetType()] - 1;
}
protected override void Finalize()
{
this._counts[this.GetType()] = this._counts[this.GetType()] - 1;
}
}