2015-12-25 24 views
5

在我的项目中,我经常想要一个私有的方法(或者如果你喜欢的话),但是我也想从一个其他类访问它。这有可能吗?Private-ish方法?

要澄清,此方法可以从ClassA,它自己的类,但没有任何其他访问。

+2

如果您将两个类都放入专用于这两个类的程序集中,则可以使用'internal'。但是......你可能想重新思考为什么你需要这样做。 –

+0

这种设计背后的理性是什么? – dotctor

+0

可能的重复:http://stackoverflow.com/questions/203616/why-does-c-sharp-not-provide-the-c-style-friend-keyword –

回答

2

有很多方法可以做到这一点,直到你的最后一个声明是“只有那个类”,我只能想到一种方法来做到这一点,它是在类似于:

大会一个只包含A级与要声明为内部的方法

组件B声明为友好装配:https://msdn.microsoft.com/en-us/library/0tke9fxk.aspx和包含的代码来调用A(它可以为它,它是内部仿佛在相同的装配,因为它是一个朋友大会)

没有其他大会链接到A,B或两者将能够调用A类的方法,因为它是内部的。

+0

我认为这是做到这一点的唯一方法。 – dotctor

1

无论你问的是在C#中不可能的。我的意思是你不能只允许一个类使用私有方法。你所能做的只是使用internal,它允许只有一个程序集的类访问你的方法或protected,它可以在其类和派生类实例内访问!

除此之外没有为你问什么,但你可以做一些黑客任何经验法则,如下图所示:

MethodInfo privateMethod = instance.GetType().GetMethod("NameOfPrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance); 
privateMethod.Invoke(instance, new object[] { methodParameters }); 
0

一个稍微卑鄙的手段来使用的方法,由B类A类是使该方法受保护而不是私有,并从B中派生A.

另一种可能更好的方法是使方法内部而不是私有,然后将类A和B放入同一个程序集中。

2

可以使此方法保护的,如果它适合你的OOP结构:

public class A 
{ 
    protected void Test() 
    { 
     Console.WriteLine("I can only be called from B"); 
    } 
} 

public class B : A 
{ 
    public void Pub() 
    { 
     Test(); 
    } 
} 

还有许多其他的方法可以做到这一点。

但是,一般来说,这听起来像是对访问修饰符的错误看法。
如果您只想从一个地方调用您的方法,那么只需从一个地方调用它。
这个方法应该从另一个类中调用,这使得它在公共,逻辑和体系结构上都是公开的。

+0

从'A'派生的每个类都可以访问'Test'方法。 OP想要“但是我也想从一个其他课程访问它,而只有其他课程!” – dotctor

2

我能想到的最佳方式就是这样。

在C#5中,添加了一组呼叫者信息属性,即[System.Runtime.CompilerServices.CallerMemberName],[System.Runtime.CompilerServices.CallerFilePath][System.Runtime.CompilerServices.CallerLineNumber]。我们可以使用CallerFilePathAttribute来查看调用者是否来自特定的.cs文件。

通常,一个文件将只包含一个类或结构。例如,ClassAClassA.cs中定义。您可以检查方法中的呼叫方文件名是否与ClassA.cs匹配。

所以修改方法的参数是这样的:

([CallerFilePath] string callerFilePath = "" /*Other parameters*/) 

在该方法中,检查callerFilePathClassA文件路径相匹配。如果没有,请抛出一个异常,说只能从ClassA访问该方法!

+0

该检查仅在运行时完成。 – dotctor

+0

是的......我知道。但是,您仍然不能在ClassA以外的类中使用该方法。所以它符合要求! @dotctor – Sweeper

1

控制成员访问的另一个简单方法是使用委托。 让我们假设你有一个私有方法:

class SecureMethod { 
    private void DoSomething() { } 
} 

您可以通过注入授人以这种方法可以访问这个方法:

class ClassA { 
public ClassA(Action secureMethod) { } 
} 

SecureMethod objWithSecureMethod; 
var a = new ClassA(objWithSecureMethod.DoSomething); 
1

我展示你如何做到这一点,但这些都是非常糟糕的做法:

public class A 
{ 
    private void CanOnlyCallMethodInClassB(); 
    public static void SetHandlerCanOnlyCallMethodInClassB(ClassB b) 
    { 
     b.MethodFromClassA = CanOnlyCallMethodInClassB; 
    } 
} 
public class B 
{ 
    public Action MethodFromClassA { get; set; } 
} 

代码:

var b = new B(); 
A.SetHandlerCanOnlyCallMethodInClassB(b); 
b.MethodFromClassA(); 

更好方法是在方法classA中使用ClassB的对象。搜索谷歌搜索策略模式或使用继承