How to use a same StreamWriter across various methods in a class. For eg.
public class XMLWriter
{
public export(string filename)
{
StreamWriter sw = new StreamWriter(filename)
sw.write("Line1")
}
public footer()
{
// Note: I am not declaring streamwriter here since i want to use the same sw as in export method
sw.write("Line x N")
}
}
How can I use the same sw across many methods. Also this class will be instantiated from another class and the "public" methods will be called from there.
Any help will be highly appreciated.
Declare sw as a global variable, and only close and dispose it when you dispose your XMLWriter object (or when you know you won't write more into your file) with calling the DisposeWriter() method below from the class where you created that object:
public class MyClass
{
private void DoSomeStuff()
{
XMLWriter xmlwr = new XMLWriter();
xmlwr.export(#"C:\YourFile.txt");
xmlwr.footer();
xmlwr.DisposeWriter();
wmlwr = null;
}
}
public class XMLWriter
{
private StreamWriter sw;
public XMLWriter()
{
//this is the constructor, what you call with "new XMLWriter()"
}
public void export(string filename)
{
sw = new StreamWriter(filename)
sw.write("Line1")
}
public void footer()
{
sw.write("Line x N")
}
public void DisposeWriter()
{
sw.Close();
sw.Dispose();
}
}
I would just declare thee steamwriter above the methods (global variable) and do the work inside the methods
Pass it as parameter or use a private field - depends on you requirements.
using System;
using System.IO;
using System.Text;
public class XMLWriter
{
//Objs
private StreamWriter sw;
private StringBuilder sb;
//static items
private string strHeader;
private string strFooter;
public XMLWriter()
{
//this is the constructor, what you call with "new XMLWriter()"
}
public void export(string filename)
{
sb = new StringBuilder();
sw = new StreamWriter(filename);
sw.Write(strHeader + sb.ToString() + strFooter);
sw.Close();
sw.Dispose();
}
public string Footer
{
set
{
strFooter = value;
}
}
public string Header
{
set
{
strHeader = value;
}
}
public string LinesAdd
{
set
{
sb.Append(value);
}
}
}
Related
How can I create deserialization method that can take an object of class or any of derived classes?
public class Config
{
public string appname;
}
public class CustomConfig1 : Config
{
public string CustomConfig1Param1;
public string CustomConfig1Param2;
}
public class CustomConfig2 : Config
{
public string CustomConfig2Param1;
public string CustomConfig2Param2;
}
I want to get something like serialization method that defines type of input object:
public string serialize(object obj)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
StringWriter serialized = new StringWriter();
serializer.Serialize(serialized, obj);
return serialized.ToString();
}
But when I read an XML from DB I can't define the type of object, so I can't pass it to XmlSerializer. It may be the Config object or any of derived classes
Please help. How can I define the type of input object?
[XmlInclude(typeof(CustomConfig1))]
[XmlInclude(typeof(CustomConfig2))]
public class Config
{
public string appname;
}
Then just serialize/deserialize specifying typeof(Config); the library will give you back an instance of the appropriate type based on the data.
Edit: full example, including the preference to not hard-code the sub-types:
using System;
using System.IO;
using System.Xml.Serialization;
public class Config
{
public string appname;
}
public class CustomConfig1 : Config
{
public string CustomConfig1Param1;
public string CustomConfig1Param2;
}
public class CustomConfig2 : Config
{
public string CustomConfig2Param1;
public string CustomConfig2Param2;
}
static class Program
{
static void Main()
{
var original = new CustomConfig1
{
appname = "foo",
CustomConfig1Param1 = "x",
CustomConfig1Param2 = "y"
};
var xml = Serialize(original);
var clone = DeserializeConfig(xml);
Console.WriteLine(clone.appname);
var typed = (CustomConfig1)clone;
Console.WriteLine(typed.CustomConfig1Param1);
Console.WriteLine(typed.CustomConfig1Param2);
}
public static string Serialize(Config obj)
{
using (var serialized = new StringWriter())
{
GetConfigSerializer().Serialize(serialized, obj);
return serialized.ToString();
}
}
public static Config DeserializeConfig(string xml)
{
using(var reader = new StringReader(xml))
{
return (Config)GetConfigSerializer().Deserialize(reader);
}
}
static Type[] GetKnownTypes()
{
// TODO: resolve types properly
return new[] { typeof(CustomConfig1), typeof(CustomConfig2) };
}
private static XmlSerializer configSerializer;
public static XmlSerializer GetConfigSerializer()
{
return configSerializer ?? (configSerializer =
new XmlSerializer(typeof(Config), GetKnownTypes()));
}
}
I have a class I found on another post that I'm trying to modify.
using System;
using System.IO;
namespace Misc
{
internal class ConfigManager
{
private string _sConfigFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}.xml", AppDomain.CurrentDomain.FriendlyName));
private Config m_oConfig = new Config();
public Config MyConfig
{
get { return m_oConfig; }
set { m_oConfig = value; }
}
// Load configuration file
public void LoadConfig()
{
if (System.IO.File.Exists(_sConfigFileName))
{
System.IO.StreamReader srReader = System.IO.File.OpenText(_sConfigFileName);
Type tType = m_oConfig.GetType();
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
object oData = xsSerializer.Deserialize(srReader);
m_oConfig = (Config)oData;
srReader.Close();
}
}
// Save configuration file
public void SaveConfig()
{
System.IO.StreamWriter swWriter = System.IO.File.CreateText(_sConfigFileName);
Type tType = m_oConfig.GetType();
if (tType.IsSerializable)
{
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
xsSerializer.Serialize(swWriter, m_oConfig);
swWriter.Close();
}
}
}
}
I'd like to pass in an object of type X and have it save. On that same premise, I'd like to pass in a type and have it pass back the object of type X. Right now, it is hard coded to use Config. So, if there is a way to pass in the class object (?) then I'd like it to save it as that object and/or return it of that object.
Is that possible? If so, how would I go about doing this?
Use generic:
internal class ConfigManager<T>
{
private string _fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}.xml", AppDomain.CurrentDomain.FriendlyName));
private T _config;
private XmlSerializer serializer = new XmlSerializer(typeof(T));
public T MyConfig
{
get { return _config; }
set { _config = value; }
}
public void LoadConfig()
{
if (File.Exists(_fileName))
{
using (var reader = File.OpenText(_fileName))
{
_config = (T)serializer.Deserialize(reader);
}
}
}
public void SaveConfig()
{
using (var writer = File.CreateText(_fileName))
{
serializer.Serialize(writer, _config);
}
}
}
Usage:
var man = new ConfigManager<Foo>();
Basically, we'd need to make it work with Generics. So, we start by giving it a type variable, and replace every use of the class Config with T:
internal class Manager<T>
{
private T m_oObj; // etc
Next, I'll just do one method; you can do the rest. (and I'm removed the explicit namespaces, cuz they're ugly)
using System.IO;
using System.Xml.Serialization;
public void LoadConfig<T>()
{
if (File.Exists(_sConfigFileName))
{
var srReader = File.OpenText(_sConfigFileName);
var xsSerializer = new XmlSerializer(typeof(T));
var oData = xsSerializer.Deserialize(srReader);
m_oObj = (T)oData;
srReader.Close();
}
}
How can I create deserialization method that can take an object of class or any of derived classes?
public class Config
{
public string appname;
}
public class CustomConfig1 : Config
{
public string CustomConfig1Param1;
public string CustomConfig1Param2;
}
public class CustomConfig2 : Config
{
public string CustomConfig2Param1;
public string CustomConfig2Param2;
}
I want to get something like serialization method that defines type of input object:
public string serialize(object obj)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
StringWriter serialized = new StringWriter();
serializer.Serialize(serialized, obj);
return serialized.ToString();
}
But when I read an XML from DB I can't define the type of object, so I can't pass it to XmlSerializer. It may be the Config object or any of derived classes
Please help. How can I define the type of input object?
[XmlInclude(typeof(CustomConfig1))]
[XmlInclude(typeof(CustomConfig2))]
public class Config
{
public string appname;
}
Then just serialize/deserialize specifying typeof(Config); the library will give you back an instance of the appropriate type based on the data.
Edit: full example, including the preference to not hard-code the sub-types:
using System;
using System.IO;
using System.Xml.Serialization;
public class Config
{
public string appname;
}
public class CustomConfig1 : Config
{
public string CustomConfig1Param1;
public string CustomConfig1Param2;
}
public class CustomConfig2 : Config
{
public string CustomConfig2Param1;
public string CustomConfig2Param2;
}
static class Program
{
static void Main()
{
var original = new CustomConfig1
{
appname = "foo",
CustomConfig1Param1 = "x",
CustomConfig1Param2 = "y"
};
var xml = Serialize(original);
var clone = DeserializeConfig(xml);
Console.WriteLine(clone.appname);
var typed = (CustomConfig1)clone;
Console.WriteLine(typed.CustomConfig1Param1);
Console.WriteLine(typed.CustomConfig1Param2);
}
public static string Serialize(Config obj)
{
using (var serialized = new StringWriter())
{
GetConfigSerializer().Serialize(serialized, obj);
return serialized.ToString();
}
}
public static Config DeserializeConfig(string xml)
{
using(var reader = new StringReader(xml))
{
return (Config)GetConfigSerializer().Deserialize(reader);
}
}
static Type[] GetKnownTypes()
{
// TODO: resolve types properly
return new[] { typeof(CustomConfig1), typeof(CustomConfig2) };
}
private static XmlSerializer configSerializer;
public static XmlSerializer GetConfigSerializer()
{
return configSerializer ?? (configSerializer =
new XmlSerializer(typeof(Config), GetKnownTypes()));
}
}
I have small class for text files:
using System.IO;
namespace My_Application
{
public static class FileIO
{
public static void WriteText(string filename, string text)
{
StreamWriter file = new StreamWriter(filename);
file.Write(text);
file.Close();
}
public static string ReadText(string filename)
{
StreamReader file = new StreamReader(filename);
string text = file.ReadToEnd();
file.Close();
return text;
}
}
}
My main file:
using System;
using System.Windows.Forms;
namespace My_Application
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string readTestFile()
{
// error is here:
return FileIO.ReadFile("test.txt");
}
}
}
Im getting error:
My_Application.FileIO' does not contain a definition for 'ReadFile'
This is weird, because I was using that class in another application and it worked.
Only difference I catched, is that other application had one word name without "_".
Edit/added later:
OK. My problem was bad method name. However this is still weird, because IntelliSense suggests nothing when I write FileIO. (i also tried to press ctrl-space).
Additional question: Why IntelliSense does not see these methods?
Your method is called ReadText but you're trying to call ReadFile.
Declaration:
public static string ReadText(string filename)
and usage:
return FileIO.ReadFile("test.txt");
It shouldn't be
return FileIO.ReadFile("test.txt");
It should be
return FileIO.ReadText("test.txt");
I have a method that I want to use in almost all the classes within a same c# project.
public void Log(String line)
{
var file = System.IO.Path.GetPathRoot(Environment.SystemDirectory)+ "Logs.txt";
StreamWriter logfile = new StreamWriter(file, true);
// Write to the file:
logfile.WriteLine(DateTime.Now);
logfile.WriteLine(line);
logfile.WriteLine();
// Close the stream:
logfile.Close();
}
What is the approach to reuse this method in other classes of the project?
If you want to use it in all classes, then make it static.
You could have a static LogHelper class to better organise it, like:
public static class LogHelper
{
public static void Log(String line)
{
var file = System.IO.Path.GetPathRoot(Environment.SystemDirectory)+ "Logs.txt";
StreamWriter logfile = new StreamWriter(file, true);
// Write to the file:
logfile.WriteLine(DateTime.Now);
logfile.WriteLine(line);
logfile.WriteLine();
// Close the stream:
logfile.Close();
}
}
Then call it by doing LogHelper.Log(line)
You can make a static class and put this function in that class.
public static MyStaticClass
{
public static void Log(String line)
{
// your code
}
}
Now you can call it elsewhere. (No need to instantiate because it's a static class)
MyStaticClass.Log("somestring");
You can use Extrension method in statis class
Sample on string extension
public static class MyExtensions
{
public static int YourMethod(this String str)
{
}
}
link : http://msdn.microsoft.com/fr-fr/library/vstudio/bb383977.aspx