класс не содержит определения для функции - PullRequest
0 голосов
/ 26 августа 2018

У меня есть куча классов, которые расширяют один конкретный базовый класс, см. Ниже:

public class UIBaseProperties
{

}

public class EasyRawImage : UIBaseProperties
{
    public void SetImageDimensions(float? width = null, float? height = null)
    {
        if(width == null && height == null)
            RectOptions.sizeDelta = new Vector2(Img.width, Img.height);
        else if(width != null && height == null)
            RectOptions.sizeDelta = new Vector2((float)width, (float)width/Img.width*Img.height);
        else if(width == null && height != null)
            RectOptions.sizeDelta = new Vector2((float)height/Img.height*Img.width, (float)height);
        else if(width != null && height != null)
            RectOptions.sizeDelta = new Vector2((float)width, (float)height);
    }
}

Теперь у меня есть в другом классе список UIBaseProperties, к которому я добавляю различные экземпляры, которые все происходят из UIBasePropertiesвот так:

public class OpenRecordUI
{
    private List<UIBaseProperties> UIElements;

    public OpenRecordUI()
    {
        UIElements = new List<UIBaseProperties>();
        UIElements.Add(new EasyRawImage(Resources.Load("Images/" + Data.local_photo_name), new Vector2(50, 50), v.GetActualPixelSizes().size.x, v.GetActualPixelSizes().size.y));
        var test = UIElements[0].SetImageDimensions(); // error
    }
}

Теперь я получаю ошибку, когда пытаюсь вызвать функцию SetImageDimensions ().Я получаю следующую ошибку:

«UIBaseProperties» не содержит определения для «SetImageDimensions» и метода расширения «SetImageDimensions»

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

Если что-то неясно, дайте мне знать, чтобы я мог уточнить!

Ответы [ 3 ]

0 голосов
/ 26 августа 2018

Вы можете объявить UIBaseProperties как класс abstract и SetImageDimensions как метод abstract. Затем в каждом производном классе от UIBaseProperties вы должны предоставить реализацию для этого метода.

public abstract class UIBaseProperties
{
    public abstract SetImageDimensions(float? width = null, float? height = null);
}

Тогда, переопределив SetImageDimensions, ошибка больше не будет существовать.

public class EasyRawImage : UIBaseProperties
{
    public override void SetImageDimensions(float? width = null, float? height = null)
    {
        if(width == null && height == null)
            RectOptions.sizeDelta = new Vector2(Img.width, Img.height);
        else if(width != null && height == null)
            RectOptions.sizeDelta = new Vector2((float)width, (float)width/Img.width*Img.height);
        else if(width == null && height != null)
            RectOptions.sizeDelta = new Vector2((float)height/Img.height*Img.width, (float)height);
        else if(width != null && height != null)
            RectOptions.sizeDelta = new Vector2((float)width, (float)height);
    }
}

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

// The name of the interface is not very good, you should probably 
// think for another name.
public interface IUIBaseProperties
{
    void SetImageDimensions(float? width = null, float? height = null)
}

Затем повторно объявите свой класс, как показано ниже:

public class EasyRawImage : IUIBaseProperties
{
    public void SetImageDimensions(float? width = null, float? height = null)
    {
        if(width == null && height == null)
            RectOptions.sizeDelta = new Vector2(Img.width, Img.height);
        else if(width != null && height == null)
            RectOptions.sizeDelta = new Vector2((float)width, (float)width/Img.width*Img.height);
        else if(width == null && height != null)
            RectOptions.sizeDelta = new Vector2((float)height/Img.height*Img.width, (float)height);
        else if(width != null && height != null)
            RectOptions.sizeDelta = new Vector2((float)width, (float)height);
    }
}

и используйте его, как показано ниже:

public class OpenRecordUI
{
    private List<IUIBaseProperties> UIElements;

    public OpenRecordUI()
    {
        UIElements = new List<IUIBaseProperties>();
        UIElements.Add(new EasyRawImage(Resources.Load("Images/" + Data.local_photo_name), new Vector2(50, 50), v.GetActualPixelSizes().size.x, v.GetActualPixelSizes().size.y));
        var test = UIElements[0].SetImageDimensions();
    }
}
0 голосов
/ 26 августа 2018

Причина проблемы заключается в том, что UIElements[0] имеет тип UIBaseProperties.

Если коллекция UIElements может содержать только вещи типа EasyRawImage, то она должна быть напечатана как List<EasyRawImage>, тогда вы сможете вызывать этот метод со строкой, которая у вас уже есть.

Однако, если вы намереваетесь поместить другие реализации этого базового класса в коллекцию, вам нужно оставить объявление как оноявляется;но вы должны быть уверены, что этот товар относится к этому типу, прежде чем использовать его.Вместо того, чтобы разыграть его, с помощью ((EasyRawImage)UIElements[0]) (который потерпит неудачу, если это не тот тип) вы можете сделать это:

var test = UIElements[0] asEasyRawImage;
if (test != null)
{
    test.SetImageDimensions();
}
0 голосов
/ 26 августа 2018

Ошибка говорит вам, что именно не так.Класс UIBaseProperties не имеет метода SetImageDimensions.

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

В вашем случае все в вашем списке рассматривается как экземплярUIBaseProperties, даже если они являются экземплярами дочернего класса EasyRawImage.Поскольку у родительского класса нет метода SetImageDimensions, вы не можете получить к нему доступ, даже если ваши объекты действительно его содержат.

Чтобы обойти это, вам необходимо привести каждый объект обратно к дочернему типу при доступе к нему, например, так:

((EasyRawImage)UIElements[0]).SetImageDimensions();

Это, однако, считается плохой практикой.Было бы предпочтительно не определять список как содержащий UIBaseProperties объектов в первую очередь.Вместо этого используйте что-то вроде абстрактного класса или шаблона интерфейса.

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