我有一堆类,它们都扩展了一个特定的基类,如下所示:
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'
我知道为什么会收到错误,但我不知道如何通过其他方式进行操作。
这是否有可能,否则应该怎么做?
如果不清楚,请告诉我,以便我澄清!
答案 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();
}