类不包含函数定义

时间:2018-08-26 14:51:05

标签: c# function class generics inheritance

我有一堆类,它们都扩展了一个特定的基类,如下所示:

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
    }
}

现在我在另一个类中有一个UIBaseProperties列表,我向其中添加了所有都从UIBaseProperties派生的不同实例,如下所示:

const express = require('express');
const router = express.Router();

module.exports = function (app, models) {

    router.put('/', function (req, res) {

    });

    function test(){

    };


    return router;
};

现在,当我尝试调用SetImageDimensions()函数时出现错误。我得到的错误如下:

  

'UIBaseProperties'不包含'SetImageDimensions'的定义,也没有扩展方法'SetImageDimensions'

我知道为什么会收到错误,但我不知道如何通过其他方式进行操作。
这是否有可能,否则应该怎么做?

如果不清楚,请告诉我,以便我澄清!

3 个答案:

答案 0 :(得分:3)

您可以将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();
    }
}

答案 1 :(得分:0)

错误告诉您确切的错误。类UIBaseProperties没有方法SetImageDimensions

创建包含特定类型对象的列表时,它们都将被视为完全属于该类型。当然,您可以在其中存储从定义中的一个继承的类的实例,但仍将它们视为父类的实例。

在您的情况下,列表中的所有内容都被视为UIBaseProperties的实例,即使它们是子类EasyRawImage的实例也是如此。由于父类没有方法SetImageDimensions,因此即使您的对象确实包含它,也无法访问它。

要解决此问题,您需要在访问每个对象时将其强制转换回子类型,如下所示:

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

但是,这被认为是不良做法。最好不要首先将列表定义为包含UIBaseProperties个对象。相反,请使用诸如抽象类或接口模式之类的东西。

答案 2 :(得分:0)

问题的原因是UIElements[0]的类型为UIBaseProperties

如果UIElements集合只能包含类型EasyRawImage的东西,则应将其键入为List<EasyRawImage>,那么您将能够在已有的行中调用该方法

但是,如果您打算将该基类的其他实现放入集合中,则需要保留声明原样。但在使用前,请确保该项目属于该类型。您可以使用((EasyRawImage)UIElements[0])(如果不是该类型,它将失败),而不是进行强制转换:

var test = UIElements[0] asEasyRawImage;
if (test != null)
{
    test.SetImageDimensions();
}