Доступ к членам суперкласса - PullRequest
0 голосов
/ 26 июня 2018

Я хочу создать суперкласс, который имеет только два поля: Id и Timestamp и имеет класс, который может использовать любых потомков этого суперкласса. Вроде как использование дженериков, но я знаю, что оно будет по крайней мере иметь поле Id и timestamp.

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

Вот простой, тупой пример того, что я хочу сделать. Скажем, у меня есть следующий суперкласс:

public class Shape
{
    public double Area { get; set; }
}

Я также реализую квадрат, который происходит от Shape:

class Square : Shape
{
    public int SideLength { get; set; }
    // more stuff
}

Я хочу создать класс ShapeHandler, который принимает любой тип фигуры и может получить его площадь. Но следующий код неверен :

class ShapeHandler<Shape>
{
    private Shape MyShape;

    public double GetArea()
    {
        return MyShape.Area;
    }
}

Я бы хотел сделать это:

var sh = new ShapeHandler<Square>();
sh.GetArea();

Имеет ли этот вопрос смысл? Есть ли правильный способ сделать то, что я хочу сделать?

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Это не Shape, который вы ищете.

class ShapeHandler<Shape>
{
    private Shape MyShape;

Shape в этом фрагменте - , а не * класс Shape, это аргумент общего типа , называемый Shape. Для всех намерений и целей, как написано, это object.

Если вы действительно хотите, чтобы ShapeHandler был универсальным, вы обычно делаете интерфейс (IShape) и ограничение универсального типа:

class ShapeHandler<T> where T : IShape

Хотя ограничение может быть и против конкретного класса. Но нет никакой реальной причины для того, чтобы он вообще был вообще , просто возьмите / сохраните ссылку на базовый класс и назовите ее хорошей.

 class ShapeHandler
  {
      public ShapeHandler(Shape shape)
      {
          MyShape = shape;
      }
  }

Еще одна вещь, MyShape - это поле в вашем коде, и поэтому должно быть camelCase (myShape)

0 голосов
/ 26 июня 2018

Ваш синтаксис неверен:

class ShapeHandler<Shape> 

делает ваш ShapeHandler универсальным, но не ограничивает его Shape, фактически вызывает параметр Type "Shape".

То, что вы хотите сделать, это:

public class ShapeHandler<T> where T: Shape
{
    private T MyShape;

    public double GetArea()
    {
        return MyShape.Area;
    }
}

Это означает, что ваш ShapeHandler может быть создан только с типом (T) Shape (или с чем-то, что наследуется от Shape)

Одна вещь, которую нужно задать себе:

Зачем вам это нужно?

Имеет ли смысл использовать дженерики, когда вы можете просто использовать параметр типа Shape?

Исходя из ваших правок о регистрации определенных свойств, учтите следующее:

У вас есть два объекта, форма и квадрат:

var square = new Square() { Area = 4.0, SideLength = 2 };
var shape = new Shape() { Area = 3.0 };

И вы хотите распечатать свойство Area (оба они технически Shape, поэтому они оба имеют свойство Area. Вы можете создать метод, который принимает параметр Shape, и затем вы можете получить доступ ко всему, что Форма имеет:

public static void LogArea(Shape shape)
{
    Console.WriteLine(shape.Area);
}

Я сделал скрипку, чтобы продемонстрировать здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...