Reputation: 55
I have no idea if this is possible but it feels like it should be from using C# up to this point.
I want to have a bunch of static classes that contain 'set values' for users of the library to send into another class as parameter.
So this is where I was headed but I can't figure it out. This below is just an example of what I was thinking so don't try and work out 'why' :-)
First - The Class that will be called
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 - The Class I want to user to pass
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;
}
}
Lastly the way I want to be able to call it
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()
}
Thanks in advance... and yes, "your nuts there is a much better way" is a perfectly valid answer :-)
I would also LOVE to know how to add a .dispose() to my code, it's not something i have got to yet but while I am here... :-D
Upvotes: 1
Views: 1477
Reputation: 112437
No. This is not possible. It is not possible because of 2 reasons:
Static classes cannot be passed around.
The receiver cannot know that these classes are supposed to contain the same set of settings and has no way to access them.
Choose another approach where there is only one non-static file type class used to create several setting objects: (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; }
}
The static settings class can now present several setting objects of the same type that can be passed around.
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);
}
Now, the test class could be written as:
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}");
}
}
And you can perform the test like this
var test = new MyTestClass(SettingModule.TxtFileType, @"c:\temp\test.txt");
test.Execute();
Non-static classes are a kind of template from which numerous objects can be created. Unlike static classes, such classes are types that can be used to declare variables, method parameters, properties and more.
Upvotes: 3
Reputation: 26917
Unfortunately in C# static classes are extremely limited in what they will allow you to do.
However, with Reflection and Type
s, you can do something similar, but I don't think you should.
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;
}
}
I think what you should do is create instances of a subclass and pass that:
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);
}
You can even make it written more like your static class:
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
};
}
Upvotes: 0
Reputation: 1063013
No, basically; but you could do this:
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);
}
and pass SettingMobule.FileTypeA
as an instance, etc.
Upvotes: 5