2013-08-16 2 views
0

Я хотел бы, чтобы несколько моих классов имели возможность сообщить мне, сколько полей в них, и я хотел бы обеспечить, чтобы все мои классы имели это наследование, например:Статическая информация в классе

// this code does not compile 
abstract class Base 
{ 
    abstract static const int FieldCount = -1 
} 

class Node : Base 
{ 
    int x, y, z; // has three fields, so: 
    override static const int FieldCount = 3; 
} 

class Way : Base 
{ 
    int w, x, y, z; // has four fields, so: 
    override static const int FieldCount = 4; 
} 

Я не могу заставить его работать, а не интерфейс или абстрактный базовый класс. Мне нужно, чтобы эта информация была доступна только с типом, а не через фактический экземпляр класса (поэтому статический).

class EnumerableDataReader<TSource> : IDataReader where TSource : Base { 
    public int FieldCount { 
     get { 
      return TSource.FieldCount <- access the static info, does not work 
     } 
    } 
} 

Есть ли способ сделать это, или будет здесь Отражение - единственный способ пойти?

Спасибо!

+1

конечно же отражение будет путь - в противном случае, что бы остановить вас сообщать неправильный номер, даже если бы был способ сделать синтаксический работу? – Jon

+0

Вы не можете использовать полиморфизм для статических членов. Вы можете использовать 'override' только для методов, событий и свойств. не с 'Fields' или' Constants' –

+0

@James, даже если Op изменяет свойство, это тоже не сработает. поскольку член является ** статическим ** –

ответ

0

Не похоже, есть ли реальная необходимость в использовании полей, специально здесь, если вы перешли на использование свойств вместо этого вы могли бы переопределить реализацию свойств на каждом выводе т.е.

abstract class Base 
{ 
    public static int FieldCount { get { return -1; } } 
} 

class Node : Base 
{ 
    int x, y, z; // has three fields, so: 
    public new static int FieldCount { get { return 3; } } 
} 

class Way : Base 
{ 
    int w, x, y, z; // has four fields, so: 
    public new static int FieldCount { get { return 4; } } 
} 
... 
Console.WriteLine(Base.FieldCount) // -1 
Console.WriteLine(Node.FieldCount) // 3 
Console.WriteLine(Way.FieldCount) // 4 

Чтобы решить вторую половину ваша проблеме, вам нужно будет полагаться на отражении т.е.

class EnumerableDataReader<TSource> where TSource : Base 
{ 
    public int FieldCount 
    { 
     get { 
      return (int)typeof(TSource).GetProperties().Single(x => x.Name == "FieldCount").GetValue(null); 
     } 
    } 
} 
... 
var reader = new EnumerableDataReader<Node>(); 
Console.WriteLine(reader.FieldCount); // 3 
0

статических членов не поддерживает виртуальное наследование, потому что виртуальное наследование о решении члена данного экземпляра. Статические члены не существуют на экземплярах.

Вы можете использовать отражение для чтения статических элементов, заданных параметром типа или экземпляром Type.

В вашем дизайне много «магии». Новый разработчик может не сразу принять соглашение о создании специально названного поля. Я бы подумал об изменении дизайна до пользовательского атрибута на ваших TSource типах.

0

Вы можете использовать отдельный статический класс для хранения счетчика полей или любых конкретных данных. Статические поля в статическом классе являются уникальными для каждого типа, что означает, что MyStaticClass.FieldCount является отдельной переменной из MyStaticClass.FieldCount.

Кроме того, вы можете использовать статический конструктор, чтобы установить значение первого типа, к которому был затронут класс.

Например,

public static class FieldCountStatic<T> 
{ 
    public static int FieldCount { get; set; } 
} 

class Node 
{ 
    static Node() 
    { 
     FieldCountStatic<Node>.FieldCount = 3; 
    } 

    int x, y, z; 
} 

class Way 
{ 
    static Way() 
    { 
     FieldCountStatic<Way>.FieldCount = 4; 
    } 

    int w, x, y, z; // has four fields 

} 

class EnumerableDataReader<TSource> : IDataReader 
{ 
    public int FieldCount 
    { 
     get 
     { 
      return FieldCountStatic<TSource>.FieldCount; 
     } 
    } 
} 
Смежные вопросы