是否有可能选择性地选择(使用装饰器?)基于被调用的构造函数向对象公开的方法是什么?
例如,我的类有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
答案 0 :(得分:1)
这表明您应该有两种不同的类型。也许它们都应该是父类型的子类型(可能是抽象的),或者也许应该只是扩展另一类。
然后,您可以根据是否有字符串构造适当类型的实例。带字符串的类型可以有一个额外的方法。
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
答案 1 :(得分:1)
不直接。你可以:
创建一个返回类型为IMyInterface
的对象的工厂方法,然后尝试强制转换为包含要公开的方法的类型。如果对象不是暴露方法的类型,则强制转换将失败。或..
使用dynamic
个对象。如果方法不存在,方法调用将在运行时失败。
答案 2 :(得分:0)
这是可能的,只是不是你在这里展示的方式。您可能希望创建一个只有默认构造函数且没有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; }
}
如果你绝对必须具有选择性,这在我看来是一个愚蠢的设计决定,那么你会想要使用在运行时使用代码生成构建的类型,该代码生成或不实现该方法。
答案 3 :(得分:0)
据我所知,不,这不可能以你的意思完成。如果可以的话,编译器通常无法知道相关方法是否对相关对象有效。然后它必须在运行时检查。如果在不可用时调用该方法,则会收到运行时异常。您可以根据构造函数中设置的标志自行抛出异常。
但是,最终,您真正想要的是一个具有其他选项的子类。这将是一种更安全的方式来启用此类功能。
答案 4 :(得分:0)
您可以使用工厂模式执行此操作并返回不同的界面
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();
}
}