再次免责声明免责声明仍在学习C#和OOP,所以我希望你能耐心等待我:)
我目前正在使用一个名为FileVersion
的CMS的CMS,它基本上包含与文件相关的属性列表,例如文件名,文件类型,字节大小,id,上传日期,is-latest-版本等
FileVersion
的列表包含在File
中,其中包含自己的唯一ID。如果要从CMS下载特定文件,则使用以下内容构建URL:
string URL = "/files/"+file.id.toString()+"/"+file.fileVersion.Last().filename;
现在对于我正在处理的特定控件(专门处理文档文件),能够将URL与所有其他FileVersion
信息一起存储以供以后使用是有意义的。所以我决定创建自己的名为DocumentVersion
的类,它扩展了FileVersion
。这就是它的样子:
public partial class DocumentVersion : FileVersion
{
public DocumentVersion() : base() { }
public string link;
}
现在我应该注意,似乎我不需要在这里实现一个接口 - 但是不要把它作为福音,这就是我在这里的原因。
但是,当我尝试将FileVersion
投射为DocumentVersion
时,就像这样:
DocumentVersion dv = ((DocumentVersion)fileversion);
我得到以下异常:
无法投射类型的对象 输入'Foo.CMS.FileVersion' 'CoA.DocumentVersion'。
我的意思是,这是因为我试图将一个类扩展到原来所在的不同名称空间中,但就像我说的那样,OOP对我来说相对较新,所以我可能错了。
提前感谢您的帮助。这个社区非常有价值!我只希望一旦我更熟练,我就可以回馈一下:)。
答案 0 :(得分:5)
FileVersion
并声明它是DocumentVersion
?
如果是这样,你不能这样做,因为你所拥有的只不过是FileVersion
。
相反,您需要创建一个新 DocumentVersion
对象。您的DocumentVersion
构造函数将获取FileVersion
所需的参数,然后通过FileVersion
调用base()
构造函数。
请注意,如果您有一个现有的FileVersion
对象,则可能需要一个对象 wrap ,而不是从中获取对象。例如您的DocumentVersion
不会来自FileVersion
,但包含对FileVersion
的私人引用,以及所需的其他数据。在这种情况下,这可能更合适。
e.g。 (在OO术语中,这是组合)
public class DocumentVersion {
private FileVersion fv;
private String url;
public DocumentVersion(FileVersion fv, String url) {
this.fv = fv;
this.url = url;
}
}
有关构图的更多信息,请参阅here。
答案 1 :(得分:4)
您无法将FileVersion
转换为DocumentVersion
,因为您的fileversion变量包含FileVersion,而不是DocumentVersion。 继承表示以下内容:
如果对象是作为FileVersion创建的,那它只是一个FileVersion。期。如果它被作为DocumentVersion创建的,你可以用它无处不在那里你可以使用一个文件版本(参见上面的规则#1)的和的你可以用它的DocumentVersion功能。
因此,当创建 FileVersion对象时,您需要创建一个DocumentVersion(如果您可以控制该部分代码),那么转换将起作用。那些DocumentVersions可以存储在与FileVersions相同的列表中,因为每个DocumentVersion也是一个FileVersion。
编辑:由于上述两条规则对于理解OO原则至关重要,让我用一个例子来说明它们:DocumentVersion = dog和FileVersion = animal。然后上述规则是:(1)每只狗都是动物,但(2)并非每只动物都是狗。所以,你可以创建一个动物列表,在那里存储各种动物(狗,猫,只是“动物”的东西,...),但你不能把一个变种类型的动物投入到狗,除非什么在那里被创造为一只狗(或一只狮子狗(班贵宾犬:狗),其中是规则(1)的狗。
在OO术语中:如果将狗存储在动物类型的变量中,则对象的静态类型为“animal”,动态类型为“狗”。如果元素的动态类型为T或其子类型,则只能将元素强制转换为某种类型。
答案 2 :(得分:1)
你不能让父亲(FileVersion
)像儿子一样行事(DocumentVersion
)
只有vica versa =>你可以让儿子成为父亲。
(FileVersion)documentVersion //有效
(DocumentVersion)fileVersion //无效(因为fileVersion无法知道派生类型有的东西)
那是OOP的基础。
答案 3 :(得分:1)
DocumentVersion dv = null;
if (fileversion is DocumentVersion)
{
dv = fileversion as DocumentVersion;
}
答案 4 :(得分:1)
(正如大多数答案所说,你无法重新投票 - FileVersion
不知道DocumentVersion
是什么。
解决它的一种方法是复制DocumentVersion
public partial class DocumentVersion : FileVersion
{
public DocumentVersion() : base() { }
public DocumentVersion(FileVersion version) : this()
{
this.id = version.id;
// etc.
}
public string Link { get;set; }
}
或者在DocumentVersion
上创建一个静态方法,从您提供的DocumentVersion
返回FileVersion
,例如:
public static void New(FileVersion version)
{
this.id = version.id;
// etc.
}
提到的另一种技术是组合物。您将FileVersion
存储为DocumentVersion
public class DocumentVersion
{
public FileVersion FileVersion { get;set; }
public string Link { get;set; }
}
答案 5 :(得分:0)
由于您无法将FileVersion
转换为DocumentVersion
,而您需要做的就是添加一个获取网址的方法,您可以创建一个extension method来获取{{1} }}:
FileVersion
注意:这仅在您使用C#3.0时有效。