Я хочу создать класс «Индикатор», который будет принимать «Control» и устанавливать его свойство «Image».

Поскольку Control не имеет свойства изображения, я хочу реализовать класс шаблона ("индикатор") , который будет принимать только классы, обладающие этим свойством ( Образ).

Является ли это возможным?

8
Amit Lipman 29 Дек 2015 в 14:03

3 ответа

Лучший ответ

Мы могли изменить способ создания экземпляра этого класса, добавив закрытый конструктор без параметров и другой общедоступный ctor, в котором мы будем выполнять проверки типов:

class Indicator<T> where T : Control
{
    private T _control;

    private Indicator() 
    {
    }

    public Indicator(T control)
    {
       if(control.GetType().GetProperties().All(p => p.Name != "Image" || p.PropertyType != typeof(Image)))
       { 
          throw new ArgumentException("This type of control is not supported");
       }
       this._control = control;
    }
}
19
Fabjan 11 Авг 2018 в 22:04

Основываясь на ответе @Fabjan, вместо использования отражения для выполнения проверки типа, необходимой для идентификации свойства Image каждый раз, когда вы создаете экземпляры объекта, вы можете использовать статические конструкторы для выполнения этой проверки только когда создается сам тип :

class Indicator<T> where T : Control
{
    static Indicator()
    {
        {
            if (typeof(T).GetProperties().All(p => p.Name != "Image" || p.PropertyType != typeof(Image)))
                throw new Exception(typeof(T).Name + " is not a supported generic type argument because it does not have an Image property");
        }
    }

    private readonly T _control;
    public Indicator(T control)
    {
        _control = control;
    } 
}
0
AGB 22 Янв 2016 в 23:43

Вы можете использовать отражение, чтобы получить свойство вашего объекта:

public class ImagePropertyModifier 
{
    private PropertyInfo GetImageProperty(object obj)
    {
        var property = obj.GetType().GetProperty("Image");

        if (property == null)
            throw new Exception("Object has no Image property.");

        if (property.PropertyType != typeof(string))
            throw new Exception("Object's Image property is not a string.");

        return property;
    }

    private static string GetImage(object obj)
    {           
        return GetImageProperty(obj).GetValue(obj, null).ToString();
    }        

    private static string SetImage(object obj, string value)
    {
        GetImageProperty(obj).SetValue(obj, value);
    }        
}

Обратите внимание, что этот код предполагает, что Image - это строка (путь к изображению). Вы можете изменить тип в соответствии с вашими требованиями. Это просто пример.

4
Yeldar Kurmangaliyev 29 Дек 2015 в 11:17