The title is a bit confusing, hopefully someone maybe know's a better fitting title for my problem.
I am trying to create a class which derives from Collection<Classname> to implement an easy way to save and loading Configuration files. Writing to file is no problem, but I am not able to implement the deserialze function. I am unsure how to assign the deserialized content back to my instance.
Current approach:
[DataContract(Name = "Configurations", Namespace = "")]
public class Configurations : Collection<Configuration>
{
internal void SerializeToBinaryFile(string path)
{
Helper.DumpObjectToBinaryFile(this, path);
}
internal void DeserializeFromBinaryFile(string path)
{
// Getting Error:
// This expression can not be used as an assignment target
this = Helper.GetObjectFromBinaryFile<Collection<Configuration>>(path);
}
}
I am familiar with this.Add([Configuration]) but this just gives the opportunity to insert one item. I thought about using a foreach(Configuration c in temporaryObject and add them one by one but this can't be the best solution.
Thanks for any hint!
Edit 1:
I've added the foreach iteration for adding the Configurations
internal void DeserializeFromBinaryFile(string path)
{
foreach (var c in Helper.GetObjectFromBinaryFile<Collection<Configuration>>(path))
{
Add(c);
}
}
This seems to work fine. Does someone know a better pattern?
You cannot assign to new instance of class to "this" regardless if you are doing de-serialization or something else. Code bellow just uses new constructor and doesn't work either. Basically, you do have different 2 instances of class in memory at that point.
public class Point
{
public int X { get; set; }
public int Y { get; set; }
public void CreatePoint(int x, int y)
{
// Doesn't work either
this = new Point();
}
}
You have to do this outside of the body of the class, so rather make static deserialization method:
[DataContract(Name = "Configurations", Namespace = "")]
public class Configurations : Collection<Configuration>
{
internal void SerializeToBinaryFile(string path)
{
Helper.DumpObjectToBinaryFile(this, path);
}
internal static Configurations DeserializeFromBinaryFile(string path)
{
return Helper.GetObjectFromBinaryFile<Collection<Configuration>>(path);
}
}
Related
var test = Class1.Subclass1.Subclass2.PropertyNameWhichIsBigName
I have to use above in many places. How to avoid typing or save few key stroke? is there any shortcut in C#
Yes, you can use Namespace aliases:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/namespaces/using-namespaces
using ShortName = Class1.Subclass1.Subclass2;
And then
var test = ShortName.PropertyNameWhichIsBigName;
How about a function:
Func<typeOfProperty> someName = () => Class1.Subclass1.Subclass2.PropertyNameWhichIsBigName;
if you now call
var test = someName();
you would get your desired value without having to type the long chain of properties all the time.
Edit:
Just to be clear, if PropertyNameWhichIsBigName changes, someName() will return the new value.
You can use namespace aliasing and just call it in namespaces section in your code, and you can effectively use objects and functions all over the body #canton7 has already written example for that.
or you can use code blocks statements but you have to implement IDisposable, but this can limit your object calling section but you can get benefit fit automatic dispose.
class Class1
{
public class Subclass1
{
public class Subclass2 : IDisposable
{
public string PropertyNameWhichIsBigName { get; set; }
public void Dispose()
{
throw new NotImplementedException();
}
}
}
}
class Program
{
static void Main(string[] args)
{
using (Class1.Subclass1.Subclass2 obj = new Class1.Subclass1.Subclass2())
{
string propertiesValue = obj.PropertyNameWhichIsBigName;
}
}
}
I'm very new in C# and i need some help to use nested classes on my "Hello World" proyect.
I'm trying to create a class callable using class1.subclass1.function(args...) (to create groups of related functions), and I've done something that is working but I think that is not the best way to do it.
My code needs to share a variable between principal class and nested classes (a db handle), and I'm using and argument at class initialization to do it.
namespace SameAsPrincipal
{
public class class1
{
public SQLiteConnection handle = null;
public _subclass1 subclass = null;
public class1(string db_file)
{
handle = new SQLiteConnection(db_file);
subclass1 = new _subclass1(handle);
}
public _subclass1
{
private SQLiteConnection handle = null;
public _subclass1(SQLiteConnection handle)
{
this.handle = handle;
}
public void function(args...)
{
//Do something here
}
}
}
}
Someone knows a better way to create nested classes and share objects between main and nested?
Thanks!!
I am unclear as to why you would want to use a nested class in this instance. The way you have it written, the subclass is all you need. If you want multiple methods (or as you called them "functions") just add your methods.
Is there some hidden reason you would want to use nested classes here? As a general rule, nested classes are rarely needed.
namespace SameAsPrincipal
{
public class Class1
{
private SQLiteConnection handle;
public Class1(string db_file)
{
handle = new SQLiteConnection(db_file);
}
public int AddRecord(Record record)
{
// use handle to add record and get record Id
return record.Id;
}
public void DeleteRecord(int id)
{
// Use handle to delete record
}
}
}
When you instantiate the object you will pass in your db_file and the connection object will be created. Then every method could use that connection object when they are called. However it is usually a better idea to create the connection for each method when it is called and disposing of the connection as soon as you the operation is completed. This, of course, depends on your operations and if they are transnational. For the most part using a "using" block to instantiate your connection is a good way to use connection objects. The sooner you release the connection the sooner the machine will reuse that connection, you can lookup connection pooling to learn more.
Here is an example method that is using the "using" to add a person using a stored procedure:
public int AddPerson(Person person)
{
using (var connection = new SQLiteConnection(dbFile))
{
connection.Open();
using (var command = new SQLiteCommand("spAddPerson",connection))
{
command.CommandType = CommandType.StoredProcedure;
var idParameter = new SQLiteParameter("#Id", DbType.Int32);
idParameter.Direction = ParameterDirection.Output;
command.Parameters.Add(idParameter);
command.Parameters.AddWithValue("#FirstName", person.FirstName);
command.Parameters.AddWithValue("#LirstName", person.LastName);
command.ExecuteNonQuery();
}
}
return person.Id;
}
edit: In regard to your comment below
A few things:
Use namespaces not a parent class to group classes.
Instead of sub-classes you should just add all the database methods to the database class and create classes to model your objects.
Each class should be in it's own file
The namespace parts are ..[]* I.E. Music class has the namespace YourApplication.YourProject.Models - inside the YourProject project, within a first level folder named Music you will find a file named Music.cs and with in that file you will find your music class. This is not a requirement, the compiler does not care about structure like that. It will only make your life easier when you start to get more code developed.
Here is an example of the code structure I am speaking of (remember each of these sections is it's own file)
Create a folder at the root of your project called Models. In this Models folder create a file named Music.cs
namespace YourApplication.YourProject.Models
{
public class Music
{
public int Id { get; set; }
public string Title { get; set; }
public double Length { get; set; }
public string Artist { get; set; }
public string Album { get; set; }
}
}
In this same (Models) folder create a file called Film.cs
namespace YourApplication.YourProject.Models
{
public class Film
{
public int Id { get; set; }
public string Title { get; set; }
public double Length { get; set; }
public string Director { get; set; }
public string[] Actors { get; set; }
}
}
Now back at the project root (no longer in Models folder) create a new folder called Persistence.
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using YourApplication.YourProject.Models;
namespace YourApplication.YourProject.Persistence
{
public static class DatabaseActions
{
public static string dbFile;
public static Music[] ListMusic()
{
var musicList = new List<Music>();
// database call to get all music
using (var connection = new SQLiteConnection(dbFile))
{
connection.Open();
using (var command = new SQLiteCommand("spGetMusic", connection))
{
var reader = command.ExecuteReader();
// The try finally blocks are not strictly needed as these will are suppose to be called upon disposal
try
{
// loop through records creating music objects
while (reader.Read())
{
var music = new Music();
music.Id = reader.GetInt32(0);
music.Title = reader.GetString(1);
musicList.Add(music);
}
}
finally
{
reader.Close();
connection.Close();
}
}
}
return musicList.ToArray();
}
public static int SaveMusic(Music music)
{
if (music.Id == 0)
{
// database stuff - getting the newly created database id
}
else
{
// database calls to update record
}
return music.Id;
}
public static int SaveFilm(Film film)
{
if (film.Id == 0)
{
// database stuff - getting the newly created database id
}
else
{
// database calls to update record
}
return film.Id;
}
public static Music GetMusic(int id)
{
var music = new Music();
// database call and setting of values on music
return music;
}
public static Film GetFilm(int id)
{
var film = new Film();
// database call and setting of values on music
return film;
}
}
}
Now finally create a file on the root called WorkHarness.cs
using System;
using YourApplication.YourProject.Persistence;
namespace YourApplication.YourProject
{
public class WorkHarness
{
public void Initialize()
{
DatabaseActions.dbFile = "your db file";
}
public void ShowMusicList()
{
// list the id and title so user can select by Id
foreach (var music in DatabaseActions.ListMusic())
{
Console.WriteLine("{0,-10}{1}",music.Id,music.Title);
}
}
public void DisplayMusicItem(int id)
{
var music = DatabaseActions.GetMusic(id);
Console.WriteLine("Title: " + music.Title);
Console.WriteLine("Length: " + music.Length);
Console.WriteLine("Artist: " + music.Artist);
Console.WriteLine("Album: " + music.Album);
}
}
}
Without more context as to what the specific application is, it's hard to tell if it's appropriate or not. I agree with the previous answer that it is generally more correct to have separate classes. Your class B can still take a DB handle reference in its constructor, and class A can even pass it to it. That's fine. It's not so much that they are sharing the variable as that they both have a reference to the same DB handle.
The only time I've ever seen sub/inner classes and not thought it was weird was for like simple data objects that are only ever used within the parent class (although they may be referenced outside). For example, if I made a linked list class, I may choose to have the node class be an inner class. For just grouping functionality, regular classes should do that.
Namespaces can also be used for further grouping. For example, maybe all my text operations are in a "MyApp.Text" namespace, but then they are further grouped into classes like "NumberUtils", "NameUtils", and "ZipUtils".
Instead of nesting the objects, create two classes (at the same scope) and have one use the other, such as this:
public class ClassA
{
public ClassB InstanceOfClassB { get; set; }
public ClassA()
{
InstanceOfClassB = new ClassB();
}
//More code here
}
public class ClassB
{
//Code here
}
Using Nested classes in a HelloWorld project? Not a good sign!!
I would suggest not to use nested types Unless you know what you're doing and you have very good explanation to give when asked. Also a note of advice by .NET Framework Guidelines which explicitly recommend against creating public nested classes.
For data sharing in Object oriented programming we have inheritance feature which is the best way to share data/members access across classes based on relationship/association.
to create groups of related functions
As #Nex Terren suggested (with a little modification), you can do something like this, here your Principle class will work as Factory and different classes will provide Aggregation of related functions by their instance
public class PrincipleClass
{
public ClassB InstanceOfClassB { get; private set; }
public ClassA InstanceOfClassA { get; private set; }
public PrincipleClass(string db_file)
{
InstanceOfClassA = new ClassA(new SQLiteConnection(db_file));
InstanceOfClassB = new ClassB();
}
//More code here
}
public class ClassA
{
public ClassA(SQLiteConnection handle)
{
// your code here
}
public void FunctionOfA1() { }
public void FunctionOfA2() { }
}
public class ClassB
{
public void FunctionOfB1() { }
public void FunctionOfB2() { }
}
Now you'll have your group of function together like
new PrincipleClass.InstanceOfClassA.FunctionOfA1();
new PrincipleClass.InstanceOfClassB.FunctionOfB1();
Note - This may also not be a best solution but this is way better than using Nested types.
I'm working on very simple Roguelike game (just for myself) and get a question:
As it is not possible to create a cross-class struct-object (entity in the game case) that could be accessible from any class of my program, what to use to create a cross-class object? I was thinking of something like storing all newly created object (enities) in a static object array, but I guess there is more simple solution on this problem.
Question itself: How to create a cross-class accessible object(s) with your own properties?
Thanks everybody, I found what I was searching for.
It seems like you tried passing around a value type (a struct) between different classes and you noticed that when you update the value in one place it doesn't change the value in another place.
That's the basic difference between value types and reference types.
If you are creating the struct yourself you may want to instead define it as a class.
If not, you could wrap all your structs in a class and pass the class around as your state object.
If all you have is simply a list of the same type of struct (like Points), just pass the List itself around. C# collections are implemented as classes.
public class GameState
{
public Point PlayerLocation { get; set; }
public List<Point> BulletPoints { get; set; }
public double Health { get; set; }
}
Now you can create a GameState and pass it around to different classes:
public class Game
{
private GameState _state = new GameState();
private BulletUpdater _bulletUpdater = new BulletUpdater();
public void Update()
{
_bulletUpdater.UpdatePoints(_state);
// Points have now been modified by another class, even though a Point is a struct.
}
}
public class BulletUpdater
{
public void UpdatePoints(GameState state)
{
for (int i = 0; i < state.BulletPoints.Count; i++)
{
Point p = state.BulletPoints[i];
state.BulletPoints[i] = new Point(p.X + 1, p.Y + 1);
}
}
}
Just remember in the above code if I were to write:
Point p = state.BulletPoints[i];
p.X += 1;
p.Y += 1;
That wouldn't affect the original point! When you read a value type from a list or from a class into only copies the value into a local variable. So in order to reflect your changes in the original object stored inside the reference type you need to overwrite it like so:
state.BulletPoints[i] = p;
This same principal is why the following also will not work:
state.PlayerLocation.X += 5; // Doesn't do anything
state.PlayerLocation.Y += 5; // Also doesn't do anything
The compiler would tell you in this case that you are doing something wrong. You are only modifying the returned value of the property, not the backing field itself. You have to write it like so:
state.PlayerLocation = new Point(state.PlayerLocation.X + 5, state.PlayerLocation.Y + 5); // This works!
You can do the following:
Using IoC Framework, like Ninject. You can setup Ninject to create single instance for all usages.
The other option is to use Singleton pattern design pattern
And the third one is to use static property
It sounds like you want to use the Singleton pattern:
http://en.wikipedia.org/wiki/Singleton_pattern
Here is an example of what this would look like in C#:
public class Singleton
{
static Singleton()
{
Instance = new Singleton();
}
public static Singleton Instance { get; private set; }
}
It's possible. What about public and static class?
public static class CrossClassObject
{
public static object MyProperty { get; set; }
public static void MyMethod() {}
}
Of course this class should be placed in the same namespace that other ones.
How to use it?
class OtherClassInTheSameNamespace
{
private void SomeMethod()
{
var localVariable = CrossClassObject.MyProperty; // get 'cross-class' property MyProperty
CrossClassObject.MyMethod(); // execute 'cross-class' method MyMethod()
}
}
No idea what you are trying to achieve... but if you want a list of objects accessible 'cross-class', just make a static class with a list of objects and then when you reference your class from any other class, you will have access to its list of objects. Here is something like that:
public static class ObjectController
{
private static IList<object> existingObjects;
public static IList<object> ExistingObjects
{
get
{
if (existingObjects == null)
{
existingObjects = new List<object>();
}
}
}
}
public class MyObject
{
public MyObject()
{
ObjectController.ExistingObjects.Add(this);
}
public void Delete()
{
ObjectController.ExistingObjects.Remove(this);
}
}
Then you can add stuff like
MyObject newObj = new MyObject();
//// other stuff... This object should now be visible to whatever other class references ObjectController
newObj.Delete();
We're working with XML and want a common interface amongst the main XML class and all of its components. However, sub-components of the XML class need additional methods, but they also need the main component's methods. Seems like a great use for inheritance.
Here is some code I wrote to accomplish this task. Hopefully, you can get a good idea of what we're going for based on usage:
using System;
namespace SampleNamespace
{
public class SampleClass
{
public static void Main()
{
var xmlDocumentFiles = new XmlDocumentFiles();
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
System.Console.WriteLine(
xmlDocumentFiles.Files.RootFile.GetFileName()
);
}
}
public class XmlDocumentFilesRoot
{
protected string _rootFileName;
public FilesClass Files { get { return (FilesClass) this; } }
}
public class FilesClass : XmlDocumentFilesRoot
{
public RootFileClass RootFile { get { return (RootFileClass) this; } }
}
public class RootFileClass : FilesClass
{
public void SetFileName( string newTitle )
{
_rootFileName = newTitle;
}
public string GetFileName()
{
return _rootFileName;
}
}
public class XmlDocumentFiles : RootFileClass
{
}
}
I was able to cast to child classes and to my surprise it runs just fine. Assuming nothing is put inside of the sub-classes other than methods which wouldn't make sense in the parent, will there ever be any problems (weird compilation errors, runtime crashes) with this class structure?
Are there any alternatives? I had initially tried nested classes + extension methods located outside of the main class, but there was a lot of code needed to set that up. See: https://stackoverflow.com/questions/19415717/using-c-sharp-extension-methods-on-not-in-nested-classes-to-establish-a-common
Extending functionality of a class, sounds like a decorator pattern.
Here's a head-first pdf on this subject:
http://oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf
Also; I would like to discourage the triple '.' :
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
2 is evil, if you need 3: you will definitely lose maintainability.
Hope it helps.
I've got quite a number of classes, which have got the standard set and get methods. My problem is that many of these set methods should not be callable from outside the class which holds the objects. I'm not quite sure if there are any patterns or C# for lack of a better word - operations that would make this easier.
In reference to the code below, there are a number of classes similar to SecureSite, which the controller should be able to call functions or access variables to modify the SecureSite (and the other similar classes). However when the user asks to see SecureSite etc. they shouldn't be able to change this.
From my limited knowledge and the answers I've seen to similar questions on this site, the main issue appears to be that the Write_SecureSite can't be made fully immutable due to the List<String> AccessHistory variable. So, what I've come up with looks as ugly as a bulldogs backside and is just as messy. Essentially there is a Write version of the SecureSite class which contains a class within it, which returns a readonly version of the SecureSite class.
So, am I missing something magic in C# that would make this all so much easier?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReadOnlyExample {
public class Write_SecureSite {
private List<String> mAccessHistory;
public List<String> AccessHistory {
get {
return mAccessHistory;
}
}
public SecureSite ReadOnly {
get {
return new SecureSite(this);
}
}
public class SecureSite {
public SecureSite(Write_SecureSite aParent) {
AccessHistory=aParent.AccessHistory;
}
public IEnumerable<String> AccessHistory;
}
}
public static class Controller {
private static Write_SecureSite SimpleSecureSite=new Write_SecureSite();
public static Write_SecureSite.SecureSite Login(String MyLogin) {
SimpleSecureSite.AccessHistory.Add(MyLogin);
return SimpleSecureSite.ReadOnly;
}
public static Write_SecureSite.SecureSite Details() {
return SimpleSecureSite.ReadOnly;
}
}
public static class User {
public static void Miscellaneous() {
Controller.Login("Me");
Write_SecureSite.SecureSite SecureSite=Controller.Details();
//Not going to happen.
SecureSite.AccessHistory.Add("Me2");
//No problem.
foreach(String AccessedBy in SecureSite.AccessHistory) {
Console.Out.WriteLine("Accessed By: "+AccessedBy);
}
}
}
}
I suggest to use interfaces:
public interface IReadSecureSite
{
IEnumerable<String> AccessHistory { get; }
}
class Write_SecureSite : IReadSecureSite
{
public IList<String> AccessHistoryList { get; private set; }
public Write_SecureSite()
{
AccessHistoryList = new List<string>();
}
public IEnumerable<String> AccessHistory {
get {
return AccessHistoryList;
}
}
}
public class Controller
{
private Write_SecureSite sec= new Write_SecureSite();
public IReadSecureSite Login(string user)
{
return sec;
}
}
...
Controller ctrl = new Controller();
IReadSecureSite read = ctrl.Login("me");
foreach(string user in read.AccessHistory)
{
}
This is not so much an answer as a direction to look into. I am also struggling with the Immutable class
So far I am using my constructors to set my read-only private vars
I am using methods to update my lists internally instead of exposing them as public properties: ie. use public Void Add(string itemToAdd)
I am reading a book by Petricek and Skeet called "Real World Functional Programming" and it is helping me move in the direction you are discussing
Here is a small tutorial from the same author's that introduces some basic concepts: http://msdn.microsoft.com/en-us/library/hh297108.aspx
Hope this helps a bit
Update: I probably should have been clearer: I was looking to point you in the direction of a more functional view as opposed to rewriting the class you had listed in your question - my apologies (removed sample)