C# 是否可以在基类上创建静态字段,但会像在子类上创建一样产生影响?

C# 是否可以在基类上创建静态字段,但会像在子类上创建一样产生影响?,c#,oop,C#,Oop,我需要像下面的代码一样创建基类 public class ResourceBase { protected static IDictionary<string, XDocument> resources; protected static IDictionary<string, XDocument> Resources { get { if (resources == null)

我需要像下面的代码一样创建基类

public class ResourceBase
{
    protected static IDictionary<string, XDocument> resources;

    protected static IDictionary<string, XDocument> Resources
    {
        get
        {
            if (resources == null)
            {
                // cache XDocument instance in resources variable seperate by culture name.
                // load resx file to XDocument
            }

            return resources;                
        }
    }

    protected static string GetString(string resourceKey)
    {
        return GetString(resourceKey, System.Threading.Thread.CurrentThread.CurrentUICulture.Name);
    }

    protected static string GetString(string resourceKey, string cultureName)
    {
        // get data from XDocument instance
        var result = (
                        from rs in Resources
                        let node = rs.Value.Root.Elements(XName.Get("data")).SingleOrDefault<XElement>(x => x.Attribute(XName.Get("name")).Value == resourceKey)
                        where
                                (rs.Key == DEFAULT_CULTUREKEY || cultureName == rs.Key) &&
                                node != null
                        orderby cultureName == rs.Key descending
                        select node.Element(XName.Get("value"))
                     ).FirstOrDefault<XElement>();

        return result.Value;
    }
}
public class MainResource : ResourceBase
{
    public static string AppName
    {
        return GetString("AppName");
    }
}

public class OtherResource : ResourceBase
{
    public static string OtherName
    {
        return GetString("OtherName");
    }
}
我有一些问题,因为资源变量在基类中。所有子类都使用一些资源变量。因此,它们总是使用相同的缓存XDocument实例。你对修复我的源代码有什么想法吗

另外,我发现了一些属性,比如ContextStaticAttribute,它表示静态字段的值对于特定上下文是唯一的。我认为一个特定的上下文应该是不同的。所以,我不能用它来解决这个问题


谢谢,将基类抽象化,不提供资源实现。然后派生类可以向基类GetString方法提供它自己的资源。

使基类抽象,而不提供资源的实现。然后派生类可以向基类GetString方法提供自己的资源。

这似乎需要一个单例实现。创建基类的原因是为了共享逻辑,对吗?实现Singleton模式,使您的每个子类都有自己的实例,所有子类都共享来自基类的逻辑,而不是使所有内容都是静态的


这将允许他们在共享行为逻辑的同时拥有独立的缓存。

这似乎需要单例实现。创建基类的原因是为了共享逻辑,对吗?实现Singleton模式,使您的每个子类都有自己的实例,所有子类都共享来自基类的逻辑,而不是使所有内容都是静态的


这将允许它们在共享行为逻辑的同时拥有独立的缓存。

似乎每次都需要为子类缓存。缓存XDocument时,需要提供一个在子类中不同的密钥。您可以将其添加到基类中

abstract string ResourceName { get; };
protected static IDictionary<string, XDocument> Resources
{
    get
    {
        if (resources == null)
        {
            //Cache the XDocument with a key based on ResourceName.
        }

        return resources;                
    }
}

似乎每次都需要为子类缓存。缓存XDocument时,需要提供一个在子类中不同的密钥。您可以将其添加到基类中

abstract string ResourceName { get; };
protected static IDictionary<string, XDocument> Resources
{
    get
    {
        if (resources == null)
        {
            //Cache the XDocument with a key based on ResourceName.
        }

        return resources;                
    }
}

1.通过使用静态资源变量缓存所有依赖于子类类型的资源来解决此问题的解决方案

public class ResourceBase
{
    protected static IDictionary<Type, IDictionary<string, XDocument>> resources;
    protected static IDictionary<string, XDocument> Resources
    {
        get
        {
            if (resources == null)
            {
                // cache XDocument instance in resources variable seperate by type and culture name.
                // load resx file to XDocument
            }

            return resources;
        }
    }
}
公共类资源库
{
受保护的静态词典资源;
受保护的静态索引资源
{
得到
{
if(资源==null)
{
//将XDocument实例缓存在resources变量中,按类型和区域性名称分开。
//将resx文件加载到XDocument
}
归还资源;
}
}
}
顺便说一句,当我获得资源值时,这个解决方案每次都需要使用以下代码的子类类型。此外,我对该解决方案进行了大约10k-100k轮的测试,它可以每秒检索大约6000次操作的数据。。所以,我不能将此解决方案用于实际应用程序,因为每个web请求必须检索50多个操作

public static Type GetCallerType(Type baseClass, int skipFrames)
{
    StackTrace trace = new StackTrace(skipFrames + 1, false);
    Type callerType = null;

    for (int i = 0; i < trace.FrameCount; ++i)
    {
        StackFrame frame = trace.GetFrame(i);
        Type type = frame.GetMethod().DeclaringType;

        if (type == baseClass || IsInheritFrom(type, baseClass))
        {
            callerType = type;
        }
        else
        {
            break;
        }
     }

     if (callerType != baseClass)
        return callerType;
     else
        return null;
}
公共静态类型GetCallerType(类型基类,int skipFrames)
{
StackTrace trace=新的StackTrace(skipFrames+1,false);
类型callerType=null;
对于(int i=0;i
1.通过使用静态资源变量缓存所有资源来解决此问题的解决方案取决于子类的类型

public class ResourceBase
{
    protected static IDictionary<Type, IDictionary<string, XDocument>> resources;
    protected static IDictionary<string, XDocument> Resources
    {
        get
        {
            if (resources == null)
            {
                // cache XDocument instance in resources variable seperate by type and culture name.
                // load resx file to XDocument
            }

            return resources;
        }
    }
}
公共类资源库
{
受保护的静态词典资源;
受保护的静态索引资源
{
得到
{
if(资源==null)
{
//将XDocument实例缓存在resources变量中,按类型和区域性名称分开。
//将resx文件加载到XDocument
}
归还资源;
}
}
}
顺便说一句,当我获得资源值时,这个解决方案每次都需要使用以下代码的子类类型。此外,我对该解决方案进行了大约10k-100k轮的测试,它可以每秒检索大约6000次操作的数据。。所以,我不能将此解决方案用于实际应用程序,因为每个web请求必须检索50多个操作

public static Type GetCallerType(Type baseClass, int skipFrames)
{
    StackTrace trace = new StackTrace(skipFrames + 1, false);
    Type callerType = null;

    for (int i = 0; i < trace.FrameCount; ++i)
    {
        StackFrame frame = trace.GetFrame(i);
        Type type = frame.GetMethod().DeclaringType;

        if (type == baseClass || IsInheritFrom(type, baseClass))
        {
            callerType = type;
        }
        else
        {
            break;
        }
     }

     if (callerType != baseClass)
        return callerType;
     else
        return null;
}
公共静态类型GetCallerType(类型基类,int skipFrames)
{
StackTrace trace=新的StackTrace(skipFrames+1,false);
类型callerType=null;
对于(int i=0;i
2.仅使用方法扩展更容易解决此问题

强类型资源文件

public static class ResourceHelper
{
    const string RESOURCE_EXTENSION = "resx";
    const string DEFAULT_CULTUREKEY = "(default)";

    public static string GetString(this IDictionary<string, XDocument> resource, string resourceKey)
    {
        return resource.GetString(resourceKey, System.Threading.Thread.CurrentThread.CurrentUICulture.Name);
    }

    public static string GetString(this IDictionary<string, XDocument> resource, string resourceKey, string cultureName)
    {
        if (resource.Count == 0)
            resource.LoadResource();

        // retrieve data
    }

    public static void LoadResource(this IDictionary<string, XDocument> resource)
    {
        // logic to load resource
    }
[ResourceInfo(“~/Views/Home”,“Index”)]
公共类索引视图
{
受保护的静态IDictionary资源=新字典();
公共静态字符串标题
{
得到
{
returnresources.GetString(“Title”);
}
}
}
资源帮助文件

public static class ResourceHelper
{
    const string RESOURCE_EXTENSION = "resx";
    const string DEFAULT_CULTUREKEY = "(default)";

    public static string GetString(this IDictionary<string, XDocument> resource, string resourceKey)
    {
        return resource.GetString(resourceKey, System.Threading.Thread.CurrentThread.CurrentUICulture.Name);
    }

    public static string GetString(this IDictionary<string, XDocument> resource, string resourceKey, string cultureName)
    {
        if (resource.Count == 0)
            resource.LoadResource();

        // retrieve data
    }

    public static void LoadResource(this IDictionary<string, XDocument> resource)
    {
        // logic to load resource
    }
公共静态类ResourceHelper
{
const string RESOURCE_EXTENSION=“resx”;
常量字符串DEFAULT_CULTUREKEY=“(默认)”;
公共静态字符串GetString(此IDictionary资源,字符串resourceKey)
{
返回resource.GetString(resourceKey,System.Threading.T