3

是否可以有选择地选择(可能使用装饰器?)基于被调用的构造函数向对象公开哪些方法?

例如,我的类有 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
4

5 回答 5

1

不是直接的。你可以:

  1. 创建一个返回 type 对象的工厂方法,IMyInterface然后尝试强制转换为包含您希望公开的方法的类型。如果对象不是公开方法的类型,则强制转换将失败。或者..

  2. 使用一个dynamic对象。如果方法不存在,则方法调用将在运行时失败。

于 2013-10-24T19:24:56.533 回答
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
于 2013-10-24T19:20:47.213 回答
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();
    }
}
于 2013-10-24T19:28:11.270 回答
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; }
}

如果您绝对必须具有选择性,在我看来这是一个愚蠢的设计决定,那么您将希望使用在运行时使用代码生成构建的类型,该代码生成实现或不实现该方法。

于 2013-10-24T19:20:40.463 回答
0

据我所知,不,这不能按照您的意思进行。如果可以,编译器通常无法知道所讨论的方法是否对所讨论的对象有效。然后它必须在运行时进行检查。如果您在不可用时调用该方法,您将收到运行时异常。您可以根据构造函数中设置的标志自己抛出异常。

但是,最终,您真正想要的可能是具有附加选项的子类。这将是启用此类功能的一种更安全的方法。

于 2013-10-24T19:22:23.497 回答