Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何与派生类正确共享基类静态属性_C#_Class_Inheritance_Static - Fatal编程技术网

C# 如何与派生类正确共享基类静态属性

C# 如何与派生类正确共享基类静态属性,c#,class,inheritance,static,C#,Class,Inheritance,Static,我有一个基类,它包含执行http请求的基本逻辑。但是,我需要某种类型的切换,因为依赖于用户设置的配置,url的域将发生变化 基于此,我创建了一个静态属性,该属性包含一个枚举,负责为我提供所需的基值。最重要的是,基类将通过nuget包分发,因此它对用户来说有些密封,用户只需实现其必需的字段,就可以使用在其父类上定义的任何逻辑 到目前为止,我基本上提出了这个解决方案 public abstract class Base{ protected static Environment Enviro

我有一个基类,它包含执行http请求的基本逻辑。但是,我需要某种类型的切换,因为依赖于用户设置的配置,url的域将发生变化

基于此,我创建了一个静态属性,该属性包含一个枚举,负责为我提供所需的基值。最重要的是,基类将通过nuget包分发,因此它对用户来说有些密封,用户只需实现其必需的字段,就可以使用在其父类上定义的任何逻辑

到目前为止,我基本上提出了这个解决方案

public abstract class Base{
    protected static Environment Environment { get; set; }
    public static Init(Environment NewEnvironment){
        Environment = NewEnvironment;
    }
    public void UseEnvironment(){
        //use the selected environment on the method
    }
}

public A : Base{ 
    public void UseAEnvironment(){
        UseEnvironment(); //using the environment defined with A.init() call
    }
}
public B : Base{ 
    public void UseBEnvironment(){
        UseEnvironment(); //using the environment defined with B.init() call
    }
我知道内存中只有静态属性的一个副本,所以当您为a类设置一个值时,B将使用相同的值

我需要能够做到

A.Init(Environment.Debug);
B.Init(Environment.Release);
因此,当我运行程序时,类A中定义的所有方法都将使用Debug值运行,而类B将使用Release值


我的解决方案不能满足我的需要,是否有办法让它工作,或者是否有更好的架构决策来避免这种情况并实现类似的结果?

这似乎是一个有点奇怪的设计。也许像编译器指令(#if DEBUG)或通过App.config或类似的配置更合适

无论如何,如果不是。。像下面这样的方法应该可以奏效

public abstract class Base<T> where T : Base<T>
{
    private static readonly IDictionary<Type, Environment> _Environments = new Dictionary<Type, Environment>();

    public static void Init(Environment NewEnvironment)
    {
        _Environments[typeof(T)] = NewEnvironment;
    }

    protected Environment GetEnvironment()
    {
        if (!_Environments.ContainsKey(typeof(T)))
            return default(Environment);

        return _Environments[typeof(T)];
    }

}

public class A : Base<A> {
   // ...
}
public class B : Base<B> {
    // ...
}
公共抽象类基类,其中T:Base
{
私有静态只读IDictionary _Environments=new Dictionary();
公共静态void Init(环境NewEnvironment)
{
_环境[类型(T)]=新环境;
}
受保护的环境GetEnvironment()
{
if(!_Environments.ContainsKey(typeof(T)))
返回默认值(环境);
返回_环境[类型(T)];
}
}
公共A类:基本类{
// ...
}
B类公共服务:基本服务{
// ...
}

这看起来有点奇怪。也许像编译器指令(#if DEBUG)或通过App.config或类似的配置更合适

无论如何,如果不是。。像下面这样的方法应该可以奏效

public abstract class Base<T> where T : Base<T>
{
    private static readonly IDictionary<Type, Environment> _Environments = new Dictionary<Type, Environment>();

    public static void Init(Environment NewEnvironment)
    {
        _Environments[typeof(T)] = NewEnvironment;
    }

    protected Environment GetEnvironment()
    {
        if (!_Environments.ContainsKey(typeof(T)))
            return default(Environment);

        return _Environments[typeof(T)];
    }

}

public class A : Base<A> {
   // ...
}
public class B : Base<B> {
    // ...
}
公共抽象类基类,其中T:Base
{
私有静态只读IDictionary _Environments=new Dictionary();
公共静态void Init(环境NewEnvironment)
{
_环境[类型(T)]=新环境;
}
受保护的环境GetEnvironment()
{
if(!_Environments.ContainsKey(typeof(T)))
返回默认值(环境);
返回_环境[类型(T)];
}
}
公共A类:基本类{
// ...
}
B类公共服务:基本服务{
// ...
}

我不喜欢下面建议的代码,但它代表了最小数量的代码变动,以提供我认为您正在尝试做的事情。请注意,在抽象基类中删除了静态声明

public abstract class Base {
    protected Environment Environment { get; set; }

     public Init(Environment NewEnvironment) {
        Environment = NewEnvironment;
    }
}

public A : Base{ 
    public void UseEnvironment() {
     }
}
public B : Base{ 
    public void UseEnvironment() {
     }
}
然后初始化

static A DebugHttpAccess;
static B RealeaseHttpAccess;

DebugHttpAccess = new A();
DebugHttpAccess.Init(Environment.Debug);
RealeaseHttpAccess= new B();
RealeaseHttpAccess.Init(Environment.Release);
最后,按照其他更高级别的逻辑使用:

if ( needDebugHttpTracing )
    DebugHttpAccess.UseEnvironment();
else
    ReleaseHttpAccess.UseEnvironment();
我怀疑,满足您需求的正确解决方案包括控制反转和一个容器,该容器可以作为一个单例类管理Http访问的生命周期。容器将注入由其他进程范围的配置设置定义的适当Http访问实例


有关IOC容器的示例,请参见autofac.org

我不喜欢下面建议的代码,但它代表了最小数量的代码变动,以提供我认为您正在尝试的内容。请注意,在抽象基类中删除了静态声明

public abstract class Base {
    protected Environment Environment { get; set; }

     public Init(Environment NewEnvironment) {
        Environment = NewEnvironment;
    }
}

public A : Base{ 
    public void UseEnvironment() {
     }
}
public B : Base{ 
    public void UseEnvironment() {
     }
}
然后初始化

static A DebugHttpAccess;
static B RealeaseHttpAccess;

DebugHttpAccess = new A();
DebugHttpAccess.Init(Environment.Debug);
RealeaseHttpAccess= new B();
RealeaseHttpAccess.Init(Environment.Release);
最后,按照其他更高级别的逻辑使用:

if ( needDebugHttpTracing )
    DebugHttpAccess.UseEnvironment();
else
    ReleaseHttpAccess.UseEnvironment();
我怀疑,满足您需求的正确解决方案包括控制反转和一个容器,该容器可以作为一个单例类管理Http访问的生命周期。容器将注入由其他进程范围的配置设置定义的适当Http访问实例

有关IOC容器的示例,请参见autofac.org

如果您有:

public abstract class Base<T> where T : Base<T>
{
  protected static Environment Environment { get; private set; }

  public static void Init(Environment newEnvironment)
  {
    Environment = newEnvironment;
  }
}
<> p>但我认为这有点让人困惑,即使它是一个更紧凑的语法。

如果你有:

public abstract class Base<T> where T : Base<T>
{
  protected static Environment Environment { get; private set; }

  public static void Init(Environment newEnvironment)
  {
    Environment = newEnvironment;
  }
}

<> p>但我认为这会稍微混淆,即使它是一个更紧凑的语法。

如果是<代码> static ,它不属于一个实例。而且您的
环境
似乎确实应该属于一个实例。为什么它是静态的?使用静态属性不是应该避免的吗?可能您正在尝试解决一个?如果它是
静态的
,则它不属于实例。而且您的
环境
似乎确实应该属于一个实例。为什么它是静态的?使用静态属性不是应该避免的吗?也许你正在试图解决一个问题?为什么,
字典没有用,它不会有多个键,即
typeof(T)
。不同构造的泛型类型之间不共享
静态
字段
\u环境
。(见我的答案。)为什么,
字典
没有用处,它不会有多个键,即
typeof(T)
。不同构造的泛型类型之间不共享
静态
字段
\u环境
。(见我的答案)得到我的投票,这是一个比我的答案更复杂的解决方案。我仍然认为一个合适的长期解决方案将使用IOC容器,但是我很感激提供的答案是围绕问题中的示例代码形成的。好吧,但也许我应该放弃询问者希望字段
静态
的愿望,而不是修复他的代码。类似于
public abstract class Base{public abstract Environment{get;protected set;}}
这样的非静态成员可能更好。至少,这更为常见。但我不知道这到底是用来做什么的。如果我投了票,这是一个比我的答案更复杂的解决方案。我仍然认为,一个合适的长期解决方案将利用国际奥委会的容器,但我很欣赏答案是公关