【问题标题】:Using a static class as an input parameter on another class使用静态类作为另一个类的输入参数
【发布时间】:2018-05-20 23:09:45
【问题描述】:

我不知道这是否可能,但感觉应该是从使用 C# 到现在。

我想要一堆包含“设置值”的静态类,供库的用户作为参数发送到另一个类。

所以这就是我要去的地方,但我无法弄清楚。下面这只是我的想法的一个例子,所以不要试图找出“为什么”:-)

First - 将被调用的类

public class myClass
    {
        public bool isError { private set; get; }

        public DataTable output { private set; get; }

        public String filename { set; private get; }

        public settingModule settings { set; private get; }

        public static void execute()
        {


            //Call Private 'getTheData'
            //set isError accordingly
            //Load output


        }

        private static DataTable getTheData()
        {
            //Open and read file for 'fileName'

            //Use settings.startingRow
            //Use settings.fileType
            //User settings.skipEmpty

            //Do some stuff

            return Datatable from workings

        }



    }

Second - 我希望用户通过的课程

public static class settingMobule
    {
        public static class fileTypeA
        {
            public static int startingRow = 1;
            public static String fileType = "txt";
            public static bool skipEmpty = true;
        }

        public static class fileTypeB
        {
            public static int startingRow = 10;
            public static String fileType = "csv";
            public static bool skipEmpty = false;
        }

        public static class fileTypeC
        {
            public static int startingRow = 3;
            public static String fileType = "hex";
            public static bool skipEmpty = true;
        }

    }

最后是我想要的称呼方式

myClass test = new myClass();

test.filename = "c:\\temp\\test.txt;

test.settings = settingModule.fileTypeA;

test.execute();

if(test.isError == false

{
DataTable myTable = test.output;
test.dispose()
}

在此先感谢...是的,“你的疯子有更好的方法”是一个完全有效的答案:-)

我也很想知道如何将 .dispose() 添加到我的代码中,这不是我必须要做的事情,但是当我在这里时... :-D

【问题讨论】:

  • 参数必须是实例。静态类没有实例。
  • 所有这些静态类和值基本上是一个巨大的code smell,你没有构建一个好的面向对象程序。从外观上看,fileTypeAfileTypeBfileTypeC 应该是派生自同一个类的实例化类。

标签: c# class parameter-passing


【解决方案1】:

不,基本上;但你可以这样做:

public sealed class SettingMobule
{
    public int StartingRow {get; private set;}
    public string FileType {get; private set;}
    public bool SkipEmpty {get; private set;}

    private SettingMobule(int startingRow, string fileType, bool skipEmpty)
    {
        StartingRow = startingRow;
        FileType = fileType;
        SkipEmpty = skipEmpty;
    }
    public static SettingMobule FileTypeA {get;}
          = new SettingMobule(1, "txt", true);

    public static SettingMobule FileTypeB {get;}
          = new SettingMobule(10, "csv", false);

    public static SettingMobule FileTypeC {get;}
          = new SettingMobule(3, "hex", true);

}

并将SettingMobule.FileTypeA 作为实例传递,等等。

【讨论】:

  • 不要偷懒,用懒惰! :)
  • @ErikPhilips 无法解析;不知道你在那里建议什么,或者为什么这是一件好事
  • 完全搞砸了你。我通常使用private static Lazy<SettingsMobule>(..) _FileTypeA ; public static { get; } = _FileTypeA.value;,但我的意思是在这种情况下,这完全是矫枉过正。
  • 这正是我想要的工作方式!在这个例子中,主类上的参数是什么样的?公共 SettingModule 设置 { get;放; };
【解决方案2】:

没有。这不可能。这是不可能的,原因有两个:

  1. 不能传递静态类。

  2. 接收者无法知道这些类应该包含相同的设置集,并且无法访问它们。

选择另一种方法,其中只有一个非静态文件类型类用于创建多个设置对象:(C# 6.0)

public class FileType
{
    public FileType(int startingRow, string extension, bool skipEmpty)
    {
        this.StartingRow = startingRow;
        this.Extension = extension;  // 'FileType': Member names cannot be the same as their
                                     // enclosing type.
        this.SkipEmpty = skipEmpty;
    }

    public int StartingRow { get; }
    public string Extension { get; }
    public bool SkipEmpty { get; }
}

静态设置类现在可以呈现多个可以传递的相同类型的设置对象。

public static class SettingModule
{
    public static FileType TxtFileType { get; } = new FileType(1, "txt", true);
    public static FileType CsvFileType { get; } = new FileType(10, "csv", false);
    public static FileType HexFileType { get; } = new FileType(3, "hex", true);
}

现在,测试类可以写成:

public class MyTestClass
{
    private FileType fileType;
    private string filename;

    public MyTestClass(FileType fileType, string filename)
    {
        this.fileType = fileType;
        this.filename = filename;
    }

    public void Execute()
    {
        Console.WriteLine(
            $"Extension = {fileType.Extension}, starting row = {fileType.StartingRow}");
    }
}

你可以像这样进行测试

var test = new MyTestClass(SettingModule.TxtFileType, @"c:\temp\test.txt");
test.Execute();

非静态类是一种模板,可以从中创建大量对象。与静态类不同,此类类是可用于声明变量、方法参数、属性等的类型。

【讨论】:

    【解决方案3】:

    不幸的是,在 C# 中,静态类的功能极其有限。

    但是,使用 Reflection 和 Types,您可以做类似的事情,但我认为您不应该这样做。

    void Main() {
        var test = new MyClass(typeof(settingModule.fileTypeB));
        Console.WriteLine(test.StartingRow);
    }
    
    public class MyClass {
        Type SettingsClass { get; set; }
    
        public MyClass(Type sc) {
            SettingsClass = sc;
        }
    
        public int StartingRow {
            get {
                return (int)SettingsClass.GetField("startingRow", BindingFlags.Static | BindingFlags.Public).GetValue(null);
            }
        }
    }
    
    public static class settingModule {
        public static class fileTypeA {
            public static int startingRow = 1;
            public static String fileType = "txt";
            public static bool skipEmpty = true;
        }
    
        public static class fileTypeB {
            public static int startingRow = 10;
            public static String fileType = "csv";
            public static bool skipEmpty = false;
        }
    
        public static class fileTypeC {
            public static int startingRow = 3;
            public static String fileType = "hex";
            public static bool skipEmpty = true;
        }
    
    }
    

    我认为你应该做的是创建一个子类的实例并传递它:

    void Main() {
        var test = new MyClass();
        test.Settings = settingModule.fileTypeA;
        Console.WriteLine(test.Settings.startingRow);
    }
    
    public class MyClass {
        public settingModule.settingsSet Settings { get; set; }
    
    }
    
    public static class settingModule {
        public class settingsSet {
            public readonly int startingRow;
            public readonly string fileType;
            public readonly bool skipEmpty;
            public settingsSet(int sr, string ft, bool se) {
                startingRow = sr;
                fileType = ft;
                skipEmpty = se;
            }
        }
    
        public static settingsSet fileTypeA = new settingsSet(1, "txt", true);
        public static settingsSet fileTypeB = new settingsSet(10, "csv", false);
        public static settingsSet fileTypeC = new settingsSet(3, "hex", true);
    }
    

    你甚至可以让它写得更像你的静态类:

    public static class settingModule {
        public struct settingsSet {
            public int startingRow;
            public string fileType;
            public bool skipEmpty;
        }
    
        public static readonly settingsSet fileTypeA = new settingsSet {
            startingRow = 1,
            fileType = "txt",
            skipEmpty = true
        };
    
        public static readonly settingsSet fileTypeB = new settingsSet {
            startingRow = 10,
            fileType = "csv",
            skipEmpty = false
        };
    
        public static readonly settingsSet fileTypeC = new settingsSet {
            startingRow = 3,
            fileType = "hex",
            skipEmpty = true
        };
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 1970-01-01
      • 2023-03-11
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多