根据使用的构造函数有选择地公开方法
本文关键字:选择地 方法 构造函数 | 更新日期: 2023-09-27 18:36:56
有选择地选择(也许使用装饰器?)基于调用的构造函数向对象公开哪些方法?
例如,我的类有 2 个构造函数,一个是空的,另一个是传入文件路径字符串的构造函数。
public class MyClass
{
private readonly string _filePath;
public MyClass()
{
}
public MyClass(string filePath)
{
_filePath = filePath
}
public Export()
{
var fi = new FileInfo(_filePath);
}
}
当我创建一个新的 MyClass 对象时,是否有可能只有当我使用带有参数的构造函数来公开 Export 方法时?
var myClass = new MyClass();
//myClass.Export() not available
var myClass = new MyClass(@"C:'");
//myClass.Export() is available
这表明您应该有两种不同的类型。 也许它们都应该是父类型的子类型(可能是抽象的),或者也许一个应该简单地扩展另一个。
然后,可以根据是否具有字符串来构造适当类型的实例。 带有字符串的类型可以具有其他方法。
public class MyClass
{
public MyClass()
{
}
public void Foo()
{
//todo do stuff
}
}
public class BetterMyClass : MyClass
{
private readonly string _filePath;
public BetterMyClass(string filePath)
{
_filePath = filePath;
}
public void Export()
{
var fi = new FileInfo(_filePath);
}
}
然后你的用法就可以了:
var myClass = new MyClass();
//myClass.Export(); //syntax error
var myClass2 = new BetterMyClass(@"C:'");
myClass.Export(); //works
不是直接的。 您可以:
-
创建一个返回类型
IMyInterface
对象的工厂方法,然后尝试强制转换为包含要公开的方法的类型。 如果对象不是公开方法的类型,则强制转换将失败。 或。。 -
使用
dynamic
对象。 如果该方法不存在,则方法调用将在运行时失败。
这是可能的,只是不是你在这里显示的方式。您可能希望创建一个只有默认构造函数而没有Export
方法的新类。然后创建继承自第一个类的第二个类,并具有一个需要string
并公开Export
方法的构造函数。
public class MyClass
{
public MyClass()
{ }
}
public class MyOtherClass : MyClass
{
private readonly string value;
public MyOtherClass(string value)
{
this.value = value;
}
public string Export() { return this.value; }
}
如果你绝对必须具有选择性,在我看来这是一个愚蠢的设计决策,那么你会希望使用在运行时使用代码生成构建的类型,该代码生成可以实现或不实现该方法。
据我所知,不,这不能按照你的意思完成。 如果可以,编译器通常无法知道所讨论的方法是否对相关对象有效。 然后,它必须在运行时进行检查。 如果在不可用时调用该方法,则会收到运行时异常。 您可以根据构造函数中设置的标志自己引发异常。
然而,最终,你真正想要的很可能是一个具有其他选项的子类。 这将是启用此类功能的更安全方法。
您可以使用工厂模式并返回不同的接口来执行此操作
public interface IExportInterface
{
void Export();
}
public interface INoExportInterface
{
//Other methods
}
internal class MyClass : IExportInterface, INoExportInterface
{
private readonly string _filePath;
public MyClass()
{
}
public MyClass(string filePath)
{
_filePath = filePath;
}
public void Export()
{
var fi = new FileInfo(_filePath);
}
}
public class MyClassFactory
{
public static IExportInterface GetMyClass(string filePath)
{
return new MyClass(filePath);
}
public static INoExportInterface GetMyClass()
{
return new MyClass();
}
}