c#-如何允许特定类调用特定方法

c#-如何允许特定类调用特定方法,c#,class,methods,C#,Class,Methods,在我的代码中,我只需要允许classEchoProcess调用classGetStorePrivateData中的classMainData方法。我认为这不是更好的方法,但在这段代码中它可以工作。我应该怎么做 **在将来的类中,MainData将有更多受保护的类,并允许特定的其他类调用它 internal sealed class EchoProcess : MainData { private EchoProcess() { } public static s

在我的代码中,我只需要允许classEchoProcess调用classGetStorePrivateData中的classMainData方法。我认为这不是更好的方法,但在这段代码中它可以工作。我应该怎么做

**在将来的类中,MainData将有更多受保护的类,并允许特定的其他类调用它

internal sealed class EchoProcess : MainData
{
    private EchoProcess()
    {
    }

    public static string EchoPrivate(string someCondition)
    {
        var result = GetStorePrivateData<EchoProcess, Key>();
        //Condition here >
        return "";
    }

    private class Key
    {

    }
}

internal class MainData
{
    protected MainData()
    {
    }

    private static readonly List<string> StorePrivateData = new List<string>();

    protected static List<string> GetStorePrivateData<TEcho, TKey>() where TEcho : class where TKey : class
    {
        return CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>() ? StorePrivateData : null;
    }

    private static bool CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>()
    {
        var thisClass = MethodBase.GetCurrentMethod().DeclaringType;
        var echoProcessType = typeof(TEcho);
        var isEchoProcess = echoProcessType.Name == "EchoProcess";
        var keyType = typeof(TKey);
        var isKey = keyType.Name == "Key";
        var isEqualNameSpace = thisClass.Namespace.Equals(echoProcessType.Namespace) &&
                               keyType.Namespace.Equals(echoProcessType.Namespace);
        var keyTypeFullName = $"{echoProcessType.FullName}+{keyType.Name}";
        var isEqulaKeyTypeNameSpace = keyType.FullName.Equals(keyTypeFullName);
        return isEqualNameSpace && isEqulaKeyTypeNameSpace && isEchoProcess && isKey;
    }
}
内部密封类EchoProcess:主数据
{
私有EchoProcess()
{
}
公共静态字符串EchoPrivate(字符串someCondition)
{
var result=GetStorePrivateData();
//此处的条件>
返回“”;
}
私钥
{
}
}
内部类主数据
{
受保护的主数据()
{
}
私有静态只读列表StorePrivateData=新列表();
受保护的静态列表GetStorePrivateData()其中TEcho:class其中TKey:class
{
返回CheckAllowGetStorePrivateDataClassAccess()?StorePrivateData:null;
}
私有静态bool CheckAllowGetStorePrivateDataClassAccess()
{
var thisClass=MethodBase.GetCurrentMethod().DeclaringType;
var echoProcessType=类型(TEcho);
var isEchoProcess=echoProcessType.Name==“EchoProcess”;
var keyType=类型(TKey);
var isKey=keyType.Name==“Key”;
var isEqualNameSpace=thisClass.Namespace.Equals(echoProcessType.Namespace)&&
keyType.Namespace.Equals(echoProcessType.Namespace);
var keyTypeFullName=$“{echoprocestype.FullName}+{keyType.Name}”;
var isEqulaKeyTypeNameSpace=keyType.FullName.Equals(keyTypeFullName);
返回isEqualNameSpace&&isEqulaKeyTypeNameSpace&&IseChopProcess&&isKey;
}
}
在将来的类中,MainData将有更多受保护的类,并允许特定的其他类调用它

internal sealed class EchoProcess : MainData
{
    private EchoProcess()
    {
    }

    public static string EchoPrivate(string someCondition)
    {
        var result = GetStorePrivateData<EchoProcess, Key>();
        //Condition here >
        return "";
    }

    private class Key
    {

    }
}

internal class MainData
{
    protected MainData()
    {
    }

    private static readonly List<string> StorePrivateData = new List<string>();

    protected static List<string> GetStorePrivateData<TEcho, TKey>() where TEcho : class where TKey : class
    {
        return CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>() ? StorePrivateData : null;
    }

    private static bool CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>()
    {
        var thisClass = MethodBase.GetCurrentMethod().DeclaringType;
        var echoProcessType = typeof(TEcho);
        var isEchoProcess = echoProcessType.Name == "EchoProcess";
        var keyType = typeof(TKey);
        var isKey = keyType.Name == "Key";
        var isEqualNameSpace = thisClass.Namespace.Equals(echoProcessType.Namespace) &&
                               keyType.Namespace.Equals(echoProcessType.Namespace);
        var keyTypeFullName = $"{echoProcessType.FullName}+{keyType.Name}";
        var isEqulaKeyTypeNameSpace = keyType.FullName.Equals(keyTypeFullName);
        return isEqualNameSpace && isEqulaKeyTypeNameSpace && isEchoProcess && isKey;
    }
}
很高兴听到这个消息。。。我在下面提供的解决方案并不理想(例如,在编译时不会出现任何错误),有些对象模型可能更适合这种情况

在我的代码中,我只需要允许类EchoProcess从类MainData调用方法GetStorePrivateData。我认为这不是更好的方法,但在这段代码中它工作正常。我应该怎么做

编写检查调用堆栈的代码非常容易(您可以使用
var s=new StackTrace()
获取副本,并使用
s.GetFrames()
遍历堆栈)。您可以遍历调用堆栈,查看
EchoProcess
是调用方还是调用来自其他地方。下面是一个简单的例子:

static public class CallPermissionHelper
{
    static public bool IsAllowed<T>() where T : class
    {
        var callers = new StackTrace()
            .GetFrames()
            .Select
            (
                f => f.GetMethod().DeclaringType
            );
        var immediateCaller = callers.ElementAt(1);
        var firstOutsideCaller = callers
            .Skip(2)
            .Where
            (
                t => t != immediateCaller 
            )
            .FirstOrDefault();
        return (firstOutsideCaller == typeof(T));
    }
}
输出:

a=Allowed
b=Blocked

在将来的类中,MainData将有更多受保护的类,并允许特定的其他类调用它

internal sealed class EchoProcess : MainData
{
    private EchoProcess()
    {
    }

    public static string EchoPrivate(string someCondition)
    {
        var result = GetStorePrivateData<EchoProcess, Key>();
        //Condition here >
        return "";
    }

    private class Key
    {

    }
}

internal class MainData
{
    protected MainData()
    {
    }

    private static readonly List<string> StorePrivateData = new List<string>();

    protected static List<string> GetStorePrivateData<TEcho, TKey>() where TEcho : class where TKey : class
    {
        return CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>() ? StorePrivateData : null;
    }

    private static bool CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>()
    {
        var thisClass = MethodBase.GetCurrentMethod().DeclaringType;
        var echoProcessType = typeof(TEcho);
        var isEchoProcess = echoProcessType.Name == "EchoProcess";
        var keyType = typeof(TKey);
        var isKey = keyType.Name == "Key";
        var isEqualNameSpace = thisClass.Namespace.Equals(echoProcessType.Namespace) &&
                               keyType.Namespace.Equals(echoProcessType.Namespace);
        var keyTypeFullName = $"{echoProcessType.FullName}+{keyType.Name}";
        var isEqulaKeyTypeNameSpace = keyType.FullName.Equals(keyTypeFullName);
        return isEqualNameSpace && isEqulaKeyTypeNameSpace && isEchoProcess && isKey;
    }
}
很高兴听到这个消息。。。我在下面提供的解决方案并不理想(例如,在编译时不会出现任何错误),有些对象模型可能更适合这种情况

在我的代码中,我只需要允许类EchoProcess从类MainData调用方法GetStorePrivateData。我认为这不是更好的方法,但在这段代码中它工作正常。我应该怎么做

编写检查调用堆栈的代码非常容易(您可以使用
var s=new StackTrace()
获取副本,并使用
s.GetFrames()
遍历堆栈)。您可以遍历调用堆栈,查看
EchoProcess
是调用方还是调用来自其他地方。下面是一个简单的例子:

static public class CallPermissionHelper
{
    static public bool IsAllowed<T>() where T : class
    {
        var callers = new StackTrace()
            .GetFrames()
            .Select
            (
                f => f.GetMethod().DeclaringType
            );
        var immediateCaller = callers.ElementAt(1);
        var firstOutsideCaller = callers
            .Skip(2)
            .Where
            (
                t => t != immediateCaller 
            )
            .FirstOrDefault();
        return (firstOutsideCaller == typeof(T));
    }
}
输出:

a=Allowed
b=Blocked

在我的代码中,我只需要允许class
EchoProcess
callmethod
GetStorePrivateData
from class
MainData

不要对反射或堆栈跟踪执行任何此类操作

这两种类型都是
内部
。他们在同一个集会上。将要限制调用者的方法标记为
内部
。现在,程序集中的任何代码都可以调用该方法<谁在乎?你写的代码;如果您不喜欢它,您可以更改它。

这是一个问题,应该通过与编写程序集的编码人员沟通,了解使用程序集实现细节的正确协议来解决。这是一个人际团队关系问题,所以不要试图通过编写代码来解决它。将该方法标记为internal,如果您不喜欢某个调用站点,请与在代码审查期间编写该方法的开发人员交谈,以了解他们为什么认为这是一个好主意

在我的代码中,我只需要允许class
EchoProcess
callmethod
GetStorePrivateData
from class
MainData

不要对反射或堆栈跟踪执行任何此类操作

这两种类型都是
内部
。他们在同一个集会上。将要限制调用者的方法标记为
内部
。现在,程序集中的任何代码都可以调用该方法<谁在乎?你写的代码;如果您不喜欢它,您可以更改它。

这是一个问题,应该通过与编写程序集的编码人员沟通,了解使用程序集实现细节的正确协议来解决。这是一个人际团队关系问题,所以不要试图通过编写代码来解决它。将该方法标记为internal,如果您不喜欢某个调用站点,请与在代码审阅期间编写该方法的开发人员交谈,以了解他们为什么认为这是一个好主意。

请参阅,它可以访问内部内容。@JohnWu:对,您可以控制您的朋友是谁。如果您的朋友正在调用您不希望他们调用的方法,请在代码审阅中告诉他们。如果他们是坏演员,为什么他们是你的朋友?如果他们是好演员,那么你可以相信他们会遵循你的指导方针。看,这可以访问内部内容。@JohnWu:对,你可以控制你的朋友是谁。如果您的朋友正在调用您不希望他们调用的方法,请在代码审阅中告诉他们。如果他们是坏的