首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c# -如何允许特定的类调用特定的方法

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

Stack Overflow用户
提问于 2018-02-16 23:55:27
回答 2查看 940关注 0票数 0

在我的代码中,我只需要允许类GetStorePrivateData,EchoProcess,,方法,从类,MainData,,.I,这不是更好的方法,但是在这段代码中,它工作,done.How,我应该这样做吗?

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

代码语言:javascript
运行
复制
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;
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-02-17 00:59:24

在我的代码中,我只需要允许类EchoProcess调用方法GetStorePrivateData从类MainData

不使用反射或堆栈跟踪来完成这些操作。

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

这个问题应该通过与编写程序集的编码人员进行通信来解决,这些代码编写程序说明了使用程序集实现详细信息的正确协议是什么。这是一个人际关系问题,所以不要试图通过编写代码来解决它。将该方法标记为内部方法,如果有您不喜欢的调用站点,请与在代码评审期间编写该方法的开发人员交谈,找出他们为什么认为这是个好主意。

票数 3
EN

Stack Overflow用户

发布于 2018-02-17 00:17:30

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

很高兴听到这个..。下面我提供的解决方案并不理想(例如,您在编译时不会得到任何错误),而且有些对象模型可能更适合于此。

在我的代码中,我只需要允许来自MainData.I类的类EchoProcess调用方法GetStorePrivateData,我认为这不是更好的方法,但是在这段代码中,它可以工作done.How,我应该这样做吗?

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

代码语言:javascript
运行
复制
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));
    }
}

逻辑很简单:

  1. 获取从堆栈跟踪派生的调用者列表。
  2. 忽略第一个框架(它引用当前代码位置,没有多大帮助)
  3. 检查第二个框架以确定调用助手类的类。在我们的例子中,它将是MainData。我们可以忽略该类中的任何堆栈帧,例如,如果它正在调用自己或使用实用程序函数,因为它显然拥有调用自己的权限。
  4. 检查其他任何类的其他框架,在堆栈中工作。如果我们遇到的第一个类是EchoProcess,则返回true。在所有其他情况下,我们返回false。

下面是如何在您的示例中使用它:

代码语言:javascript
运行
复制
internal sealed class EchoProcess : MainData
{
    private class Key {}

    public static string GetPrivateFromMainData()
    {
        return MainData.GetStorePrivateData<EchoProcess, Key>();
    }
}

internal class MainData
{
    public static string GetStorePrivateData<TEcho, TKey>() where TEcho : class where TKey : class
    {
        var allowed = CallPermissionHelper.IsAllowed<EchoProcess>();  //Magic!!!
        return allowed ? "Allowed" : "Blocked";
    }
}

public class Program
{
    public static void Main()
    {
        var a = EchoProcess.GetPrivateFromMainData();
        var b = MainData.GetStorePrivateData<object, object>();

        Console.WriteLine("a={0}", a);
        Console.WriteLine("b={0}", b);
    }
}

输出:

代码语言:javascript
运行
复制
a=Allowed
b=Blocked

查看我在DotNetFiddle上的代码

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48836518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档