【问题标题】:Set value of a static variable using a function使用函数设置静态变量的值
【发布时间】:2018-03-22 09:05:27
【问题描述】:

我在我的解决方案中声明了一些静态变量,如下所示,

using System;
using System.Collections.Generic;
using System.Configuration;

namespace SSPWAS.Utilities
{
    public class Constants
    {
        public static string ApproverlevelL1 = "M23";
        public static string ApproverlevelL2 = "Cre";
        public static string ApproverlevelL3 = "Free34";
        public static string ApproverlevelL4 = "CDF";
        public static string ApproverlevelL5 = "FM";
    }
}

我的问题是,如果我尝试像下面这样设置它,那么我得到的错误是:

非静态字段、方法或 属性

using System;
using System.Collections.Generic;
using System.Configuration;

namespace SSPWAS.Utilities
{
    public class Constants
    {
        public static string ApproverlevelL1 = getLevel("1");
        public static string ApproverlevelL2 = getLevel("2");
        public static string ApproverlevelL3 = getLevel("3");
        public static string ApproverlevelL4 = getLevel("4");
        public static string ApproverlevelL5 = getLevel("5");
    }
}

public string getLevel(string levelID)
{
  string levelName;
  //logic here
  return levelName; 
}

那么我该如何实现呢?

【问题讨论】:

  • 你的getLevel方法在哪个类中?
  • getLevel 必须是静态方法
  • 如果要将它们用作常量,我建议将您的类成员设为const 而不是静态的,因为它们的值可以在现在声明时更改。要么那个要么static readonly
  • 相当肯定编译器向您显示了正确的错误消息。您在命名空间之外的方法

标签: c# asp.net declaration static-variables


【解决方案1】:

看起来您正试图从静态属性调用实例方法(非静态)。

尝试让你的方法静态化:

public string getLevel(string levelID)
{
  string levelName;

  //logic here
  return levelName; 
}

【讨论】:

    【解决方案2】:

    你是这个意思吗:

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    
    namespace SSPWAS.Utilities
    {
        public static class Constants
        {
            public static string ApproverlevelL1 = getLevel("1");
            public static string ApproverlevelL2 = getLevel("2");
            public static string ApproverlevelL3 = getLevel("3");
            public static string ApproverlevelL4 = getLevel("4");
            public static string ApproverlevelL5 = getLevel("5");
            private static string getLevel(string levelID)
            {
                string levelName;
                logic here
                return levelName; 
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您的问题是您希望 getLevel 方法位于不同的类中,您可以在静态类中添加一个 Function 并用该方法覆盖它。

      using System;
      using System.Collections.Generic;
      using System.Configuration;
      
      namespace SSPWAS.Utilities
      {
          public class Constants
          {
              public static Func<string, string> getLevel = x => string.Empty;
              // added get accessor to make these read only
              public static string ApproverlevelL1 { get; } = getLevel("1");
              public static string ApproverlevelL2 { get; } = getLevel("2");
              public static string ApproverlevelL3 { get; } = getLevel("3");
              public static string ApproverlevelL4 { get; } = getLevel("4");
              public static string ApproverlevelL5 { get; } = getLevel("5");
          }
      
          public class WhateverClass
          {
              public string getLevel(string levelID)
              {
                  string levelName;
                  //logic here
                  return levelName; 
              }
      
              // call this before accessing the fields in your Constants class
              public void Init()
              {
                  Constants.getLevel = x => getLevel(x);
              }
          }
      }
      

      我能想到这样做的唯一原因是你有两个应用程序使用这个静态类,它们需要以不同的方式获得关卡。也许一个使用实际的常量值,另一个读取数据库等。

      如果您不需要这样做,那么最简单的答案就是将该方法作为静态方法实际放入类中:

      namespace SSPWAS.Utilities
      {
          public class Constants
          {
              public static string getLevel(string levelID)
              {
                  string levelName;
                  //logic here
                  return levelName; 
              }
              // added get accessor to make these read only
              public static string ApproverlevelL1 { get; } = getLevel("1");
              public static string ApproverlevelL2 { get; } = getLevel("2");
              public static string ApproverlevelL3 { get; } = getLevel("3");
              public static string ApproverlevelL4 { get; } = getLevel("4");
              public static string ApproverlevelL5 { get; } = getLevel("5");
          }
      }
      

      【讨论】:

        【解决方案4】:

        你的“常数”不是常数。如果您希望它们在使用带值的静态成员初始化时表现得像常量,请将它们设为readonly。您也可以将它们设为属性并仅使用 get 访问器来调用 getLevel 方法。

        正如其他人指出的那样,如果不实例化非静态类的实例,就不能从静态成员中调用非静态成员。

        您的getLevel 方法也需要在它自己的类中。就目前而言,它不属于类或命名空间。如果您希望它在自己的单独类中,则只需将方法设置为静态。

        .NET 命名约定建议您对方法使用 Pascal 大小写。所以重命名你的 getLevel 方法。

        using System;
        using System.Collections.Generic;
        using System.Configuration;
        
        namespace SSPWAS.Utilities
        {
            public static class Constants
            {
                // Use readonly static members
                public static readonly string
                    ApproverlevelL1 = GetLevel("1"),
                    ApproverlevelL2 = GetLevel("2"),
                    ApproverlevelL3 = GetLevel("3"),
                    ApproverlevelL4 = GetLevel("4"),
                    ApproverlevelL5 = GetLevel("5");
        
                // Or you could use the latest convenient syntax
                public static string ApproverLevelL6 => GetLevel("6");
        
                // Or you could use readonly properties
                public static string ApproverLevelL7 { get { return GetLevel("7"); } }
        
                private static string GetLevel(string levelId)
                {
                    //... do logic
                    return "";
                }
            }
        }
        

        或者,如果您希望该方法在其自己的类中:

        public static class Constants
        {
            // Use readonly static members
            public static readonly string
                ApproverlevelL1 = Level.Get("1"),
                ApproverlevelL2 = Level.Get("2"),
                ApproverlevelL3 = Level.Get("3"),
                ApproverlevelL4 = Level.Get("4"),
                ApproverlevelL5 = Level.Get("5");
        
            // Or you could use the latest convenient syntax
            public static string ApproverLevelL6 => Level.Get("6");
        
            // Or you could use readonly properties
            public static string ApproverLevelL7 { get { return Level.Get("7"); } }
        }
        
        public class Level
        {
            public static string Get(string levelId)
            {
                //... do logic
                return "";
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多