以下是来自DLL的Pagina
和Scheda
的定义:
public class Pagina : BrObject
{
public const int Home = 1;
public Pagina();
public string Titolo { get; set; }
public string IDStatoPubblicazione { get; set; }
public string Descrizione { get; set; }
public string DescBreve { get; set; }
public Allegati Immagini { get; }
... many others properties
}
public class Scheda : BrObject
{
public Scheda();
public string Latitudine { get; set; }
public string SottoTitolo { get; set; }
public string Titolo { get; set; }
public PeriodiValidita PeriodiValidita { get; }
public Allegati Immagini { get; }
public Allegati Documenti { get; }
public string Descrizione { get; set; }
... many others properties
}
现在,我想做一个wrapper
课程,所以我可以把它们投到我的课堂上,只获得我需要的“一些常用参数”:
public class WrapperObject : BrObject
{
public string Titolo { get; set; }
public string Descrizione { get; set; }
public Allegati Immagini { get; set; }
public WrapperObject()
{
}
}
但是当我尝试这样做时:
IList<Pagina> ListatoPagine = GetPagine();
IList<WrapperObject> list = new List<WrapperObject>();
...
list = ListatoPagine.Cast<WrapperObject>().ToList();
失败:无法将“BrLayer.Pagina”类型的对象强制转换为“WrapperObject”。
我对OOP和C#有点生锈......
答案 0 :(得分:2)
您没有向程序提供有关如何将Pagina
的一个实例转换为包装类的任何信息。
这可以通过例如通过这个:
list = ListatoPagine.Select(x => new WrapperObject {
Titolo = x.Titolo,
Descrizione = x.Descrizione,
Immagini = x.Immagini
}).ToList();
另一种方法是在包装类中引入一个拷贝构造函数:
public class WrapperObject : BrObject
{
public string Titolo { get; set; }
public string Descrizione { get; set; }
public Allegati Immagini { get; set; }
public WrapperObject(BrObject o)
{
this.Titolo = o.Titolo;
this.Descrizione = o.Descrizione;
this.Immagini = o.Immagini;
}
}
然后可以这样调用:
list = ListatoPagine.Select(x => new WrapperClass(x)).ToList();
编辑:由于基类上不存在属性,您需要两个复制构造函数,每个导出类型一个:
public WrapperObject(Pagina o)
{
this.Titolo = o.Titolo;
this.Descrizione = o.Descrizione;
this.Immagini = o.Immagini;
}
对于另一个班级。无论如何,你最好定义一个所有类都实现的接口,并定义所有的common-properties。这样,您可以基于实现该公共接口的existiong实例创建WrapperClass
的新实例。
答案 1 :(得分:2)
继承是一种方式。
我们假设您有一个班级Oak
,然后是一个继承自Tree
的班级List<Oak>
。
您可以将List<Tree>
投射到Oak
,因为所有Tree
都是List<Tree>
。
但是你不能List<Oak>
进入Tree
,因为并非所有Oak
都是{{1}}。
你在这里遇到了完全相同的问题。
@HimBromBeere provides a solution解决您的问题。
答案 2 :(得分:2)
public class Pagina : BrObject
public class Scheda : BrObject
public class WrapperObject : BrObject
Pagina
,Scheda
和WrapperObject
是三个类,都来自BrObject
。你可以考虑他们&#34;兄弟姐妹&#34;。
这三个兄弟之间没有定义任何关系,除了他们有相同的基类。这意味着允许以下演员表:
向上投射。
这可以隐式完成,并且始终是正确的。
Pagina
至BrObject
Scheda
至BrObject
WrapperObject
至BrObject
向下投射。
这需要显式转换,仅在原始对象来自派生类(例如Pagina
)但是被转换为其基类(BrObject
)时才有效。从本质上讲,只有在你已经投降后才能抛弃(因此反转/撤消演员阵容)。
BrObject
至Pagina
BrObject
至Scheda
BrObject
至WrapperObject
Pagina
和WrapperObject
之间没有有效的演员。你不能从一个兄弟姐妹转变为另一个兄弟姐妹。
如果您使用Pagina
对象,将其转换为BrObject
,然后将其转换为Scheda
对象,编译器将不会抱怨。它相信你知道你在做什么。当你写一个明确的演员表时,你基本上凌驾于编译器的天生意义上来指出你的逻辑缺陷。
但是,运行此代码时会收到例外情况,因为Pagina
不是Scheda
,反之亦然。
没有有效的方法来强制横向(兄弟姐妹之间)。即使你设法欺骗编译器,你仍然会在运行时遇到异常。
这三个属性在Pagina
,Scheda
和WrapperObject
中定义:
public string Titolo { get; set; }
public string Descrizione { get; set; }
public Allegati Immagini { get; set; }
它们在任何地方都具有相同的名称(和类型)。但是,这是巧合。这些字段之间没有定义任何关系,它们恰好被称为相同。
作为一个简单示例,请考虑myCountry.Name
和myUser.Name
。这是两个独立的名称属性,与彼此无关。
我怀疑您需要以下OOP方法:
WrapperObject
派生自BrObject
Pagina
和Scheda
均来自WrapperObject
在此更正版本中,您始终可以隐式地将任何Pagina
对象投射到WrapperObject
。这同样适用于Scheda
请注意,从Pagina
到Scheda
仍然没有有效的演员(反之亦然),但您的问题并不表示需要这样做。
实现这个:
更正继承:
public class Pagina : WrapperObject
public class Scheda : WrapperObject
public class WrapperObject : BrObject
将这三个属性保留在WrapperObject
中,但删除来自Pagina
和Scheda
的相同属性。
您的演员现在应该按预期工作(在您的示例中):
myWrapperObjectList = myPaginaList.Cast<WrapperObject>().ToList();
现在这是一个有效的演员,因为Pagina
继承自WrapperObject
。
修改
我的同事告诉我,我很困惑&#34; up&#34; &#34; down&#34;在谈论铸造时。这引起了我们团队的争论,不是每个人都以同样的方式看待它 我的方式可能与SO上的大多数人看待它的方式不同。
但是,它与您面临的问题并不完全相关。 &#34;向上&#34; &#34; down&#34;是抽象的概念,你可以使用你喜欢的任何一个。
我将我的版本保留在这里,以便在我撰写未来评论时保持一致。
答案 3 :(得分:1)
WrapperObject
既不是Pagina
也不是Scheda
,因此您无法将其转换为WrapperObject
。这是他们的兄弟姐妹(在同一级别)。
听起来像你不需要BrObject
,而是BrObject
(父母)的集合 - 假设sht.range("30:30").api.Insert(InsertShiftDirection.xlShiftToRight)
正确设计了正确的“共享”属性。