C# - передача SomeClass функции вместо typeof(SomeClass)


Я реализовал ActionFilterAttribute, который сопоставляет SomeClass с SomeOtherClass. Вот конструктор:

public class MapToAttribute : ActionFilterAttribute
{
    private Type _typeFrom;
    private Type _typeTo;
    public int Position { get; set; }

    public MapToAttribute(Type typeFrom, Type typeTo, int Position = 0)
    {
        this.Position = Position;
        this._typeFrom = typeFrom;
        this._typeTo = typeTo;
    }

    ...
}

Способ назвать это в настоящее время:

MapTo(typeof(List<Customer>), typeof(List<CustomerMapper>), 999)

По эстетическим соображениям я предпочел бы иметь возможность делать

MapTo(List<Customer>, List<CustomerMapper>, 999)

Я пробовал делать

    public MapToAttribute(object typeFrom, object typeTo, int Position = 0)
    {
        this.Position = Position;
        this._typeFrom = typeof(typeFrom);
        this._typeTo = typeof(typeTo);
    }
Но безрезультатно, так как Visual Studio будет делать вид, что typeFrom и typeTo не определены.

Edit: (в противном случае очевидно правильное, как указано ниже) использование дженериков не поддерживается для Attributes.

2 3

2 ответа:

Нельзя использовать тип в качестве переменной. Как правило, вы можете использовать дженерики, чтобы избавиться от typeof:

public class MapToAttribute<TFrom, TTo> : ActionFilterAttribute
{
    private Type _typeFrom;
    private Type _typeTo;
    public int Position { get; set; }

    public MapToAttribute(int Position = 0)
    {
        this.Position = Position;
        this._typeFrom = typeof(TFrom);
        this._typeTo = typeof(TTo);
    }

    ...
}

Использование:

new MapToAttribute<List<Customer>, List<CustomerMapper>>(999);

Задача:
C# не допускает универсальных атрибутов, поэтому вы застряли с typeof.
Другого пути нет.

Вы не можете этого сделать. Тип не может быть передан в качестве параметра, если не используется generics или typeof. Решение Даниэля Хилгарта отлично, но не будет работать, если ваш класс предназначен для использования в качестве атрибута, поскольку c# не допускает универсальных атрибутов.