gpt4 book ai didi

c# - 隐式运算符和类层次结构

转载 作者:行者123 更新时间:2023-11-30 15:38:26 25 4
gpt4 key购买 nike

我有以下类层次结构。

public abstract class ResourceBase { }

public abstract class WebResourceBase : ResourceBase {
public ResourceBase LocalPath { get; set; }
public ResourceBase FtpPath { get; set; }
}

public class JavaScript : WebResourceBase { }

我想做的是有一个这样的声明。

new JavaScript() {
LocalPath = "/path/goes/here/1.js",
FtpPath = "ftp://path/goes/here/1.js"
}

这里明显的答案是使用隐式运算符,但问题是我想为那些与声明类型相同的属性分配派生类型,所以 LocalPathFtpPath 将是 JavaScript 类型。

我希望我的解决方案比目前的解决方案更灵活。这段代码让我毛骨悚然。希望有一种使用反射的方法,我尝试使用 StackTrace 类查找信息,但没有成功。任何帮助,将不胜感激。谢谢。

public abstract class ResourceBase { 
public static implicit operator ResourceBase(string path) {
if (path.EndsWith(".js"))
return new JavaScript(path);
// etc...
}
}

最佳答案

这假定 WebResourceBase 实际上是为了继承 ResourceBase

不幸的是,您无法使隐式运算符看起来更好——泛型在这里不起作用。


备选方案:约束 ResourceBase 的泛型

现在我已经重新阅读它并了解您的需求,一种选择是修改您的类以包含引用派生类的通用参数(有点像自引用):

public abstract class ResourceBase 
{ }

public abstract class WebResourceBase<T> : ResourceBase
where T : WebResourceBase<T>
{
public T LocalPath { get; set; }
public T FtpPath { get; set; }
}

public class JavaScript : WebResourceBase<JavaScript>
{
}

然后你会看到在 JavaScript 中,属性 LocalPathFtpPath 现在也是 JavaScript 类型.

现在您的作业将接受JavaScript 类型:

new JavaScript() 
{
LocalPath = new JavaScript("/path/goes/here/1.js"),
FtpPath = new JavaScript("ftp://path/goes/here/1.js")
}

这种方法的好处是它将基本属性限制为当前类型或更派生的类型,而不是更少的派生类型。


替代方案:显式解析而不是隐式运算符

如果您需要将 LocalPathFtpPath 变量保留为 ResourceBase,否则不能在这里使用泛型,您的隐式运算符将开始变得困惑。最好提供一些明确的东西,比如静态方法:

new JavaScript() 
{
LocalPath = JavaScript.Parse("/path/goes/here/1.js"),
FtpPath = JavaScript.Parse("ftp://path/goes/here/1.js")
}

class JavaScript
{
public static ResourceBase Parse(string s)
{
if (path.EndsWith(".js"))
return new JavaScript(path);

throw new Exception();
}
}


备选方案:类层次结构解析而不是隐式运算符

通过构造函数将使用字符串的概念烘焙到类型中,并将属性设为公共(public)只读:

public abstract class ResourceBase
{ }

public abstract class WebResourceBase
{
public ResourceBase LocalPath { get; private set; }
public ResourceBase FtpPath { get; private set; }

protected abstract ResourceBase ParseLocalPath(string s);
protected abstract ResourceBase ParseFtpPath(string s);
}

public class JavaScript : WebResourceBase<JavaScript>
{
protected override ResourceBase ParseLocalPath(string s)
{
// etc.
}
protected override ResourceBase ParseFtpPath(string s)
{
// etc.
}
}


老实说,只是为了从字符串中将两个属性设置为特定类型,其中的大部分内容似乎有点矫枉过正,您有很多选项 - 即使是隐式运算符也可以。

选择一个最容易理解的。运算符重载往往有些隐藏,除非您去挖掘它。

关于c# - 隐式运算符和类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11452881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com