Any way to create multiple versions of classes within application? - c#

Okay so i'm newbie programmer creating a little game/application just for fun in c# in visual studio 2010 using windows forms. Its a "Youtube Tycoon" and i want the player to be able to create multiple videos in the application and wondering whats the best way to go about this. I created a little console window version that just used several arrays but i wanted it to be more sophisticated.
So I have a class that has a few properties like a name and amount of views and weather its released or in production and I want the user to be able to create multiple versions of this.
Any pointers on the best way to achieve this? As i said i'm quite new to this so simple informative answers would be greatly appreciated.
Thanks in advance.

I think that you want to create multiple video objects when you say versions? As in:
var video1 = new YouTubeVideo("Some video title");
var video2 = new YouTubeVideo("Some other title");
That's how you do it. To keep track of all videos, you can keep them in collection classes like List<T>.
You can do it as:
var myVideos = new List<YouTubeVideo>();
myVideos.Add(new YouTubeVideo("Some video title"));
myVideos.Add(new YouTubeVideo("Some other title"));
The collection classes work just like arrays, but are a bit more flexible (as they can grow and shrink in size). They manage an array internally.
To remove a video you can just do:
myVideos.Remove(avideo);
and to fetch one:
var secondVideo = myVideos[1]; // <-- get the second video, as indexing starts with zero.
There are also something called LINQ which can be used to query collections:
var otherVideo = myVideos
.Where(video => video.Title.Contains("other")) // go through all videos and search for "other" in the title
.FirstOrDefault(); //return the first match or null

The best thing I can suggest in this case, since you are new to programming, is to read up on Object-Oriented programming. Here are some links to get you started:
Object-Oriented Programming (C# and Visual Basic)
Object-Oriented Concepts in C#
Once you command an understand (if only basic to begin with) of object oriented programming, you should be able to solve this question yourself.

Related

Is there a faster way to access objects exposed by VSTO/Excel

I'm writing a lot of Office add-ins in C#, and I love all the wonderful ways you can extend the functionality of especially Excel. But one thing that keeps bugging me is the overhead of doing pretty much anything to pretty much any Office object.
I'm aware that there are high-level tricks to doing many things faster, like reading and writing object[,] arrays to larger cell ranges instead of accessing individual cells, and so on. But regardless, a complicated add-in will always end up accessing lots of different objects, or many properties of a few objects, or the same properties over and over again.
And when profiling my add-ins I always find I spend at least 90% of my CPU time accessing basic properties of Office objects. For instance, here is a bit of code I use to check if a window has been scrolled, so I can update some overlay graphics accordingly:
Excel.Window window = Globals.ThisAddIn.Application.ActiveWindow;
if (window.ScrollColumn != previousScrollColumn)
{
needsRedraw = true;
previousScrollColumn = window.ScrollColumn;
}
if (window.ScrollRow != previousScrollRow)
{
needsRedraw = true;
previousScrollRow = window.ScrollRow;
}
if (window.Zoom != previousZoom)
{
needsRedraw = true;
previousZoom = window.Zoom;
}
The first line, getting the active window, and each of the if statements, each accessing a property of that window, all light up when profiling. They're really slow.
Now I know these are COM objects in managed wrappers, and there's some sort of managed->unmanaged interface stuff going on, probably inter-process communication and whatnot, so I'm not surprised that there's some overhead, but I'm still amazed at how much it adds up.
So are there any tricks for speeding stuff like this up?
For instance, in the above case I'm accessing three properties of the same object. I can't help but think there must be some way to read them all in one go, like maybe via a native companion add-in or something...?
Any ideas?
If you can get the Open XML, you can load it and traverse it using the Open XML SDK or other related libraries. Word has this (Range.WordOpenXML) but I don't know if Excel does. Even then, it might be that not all properties are exposed, for example the scroll location is probably not there.

Messages types with DataFlow Blocks

I am self-training on the TPL-Dataflow, and I have read that using immutable objects for messages is the way to go.
To comply with this, I have designed specific classes for every block inputs and outputs.
Unfortunately, when I link my block each other, because the blocks input and output types are very different, it leads to a proliferation of TransformBlock:
var proc1 = new TransformBlock<proc1In,proc1Out>(...
var convertOut1toIn2 = new TransformBlock<proc1Out,proc2In>(p1 => new proc2In { ...
var proc2 = TransformBlock<proc2In,proc2Out>(...
proc1.LinkTo(convertOut1ToIn2);
convertOut1ToIn2.LinkTo(proc2);
Using Batch and Join blocks later to merge results together makes me struggle with a very messy code.
Every samples I read on the internet uses simple types as int, string... I have not found anything that deals with a bit more complex types.
I feel the urge to use single big object and pass its reference through all the blocks. Before doing this mistake, I would like to know if there is some better way to do.
After some time musing with TPL-Dataflow, it turns out that:
Envisioning Dataflow as a conveyor belt carrying manufacturing items towards different working stations where items are enriched and built is completely wrong: doing this way leads to excruciating hard concurrency issues. Dataflow is a messaging system.
Instead, I feel it better picturing it as a mesh of people who deals with external facilities to make things (IO, Database persistence, CalculationEngines...)
The problem of messages types I dealt with is easly circumvented using Tuples. In general I dislike Tuples uglyness, but in this very situation, I feel like they really fits this place.
My problem is multiple picture analysis. Instead of having Blocks passing a "Workitem" object each other and mess with it, I rather use an separate "WorkItemSupplier" class instead. This class uses a ConcurrentDictionary of WorkItems and exposes methods to deals with workitems.
This way, my blocks in Dataflow only passes the ID of a workitem each other, so they can use the WorkItemSupplier as an external facility to store/retrieves, or change the state of any workitem.
By this way, code is running way smoothier, well separated and easier to read.

ASP.NET refering an image or asp file in a Strongly Typed fashion

Many times we need to refer another file on the server. Whether it's just an image, or another asp page. For example:
if (success)
{
img1.ImageUrl = "RightArrow.jpg"
}
The problem here is, if someone accidentally change the string "RightArrow.jpg" to "RghtArrow.jpg", it will not cause a compile time error. And it might take a lot of time to notice the run time error.
So is there any best practice here?
Of course I can build me own little mechanism for that... but I wander if there's anything build-in.
Something which is maybe strongly-typed fashioned:
img1.ImageUrl = Images.RightArrow;
Why not use Settings? If you did your code would be strongly typed, for example:
img1.ImageUrl = Settings.Default.Images.RightArrow
If you have a limited number of these resources this could be a good solution as you could even change the path/name without recompiling...
Can you just keep a List of the names of the pictures?
List<string> CollectionPictureUri = new List<string>();
CollectionPictureUri.Items.Add("RightArrow.jpg");
if (success)
{
img1.ImageUrl = CollectionPictureUri[0];
}
Or if you use a Map, then the key could just be [RightArrow]
Then you can initialize all the items in one block of code and make sure they are correct in one place.
EDIT:
You can also use asserts to validate that your strings resolve to the correct name. http://msdn.microsoft.com/en-us/library/system.diagnostics.debug.assert%28v=vs.110%29.aspx
There are other testing techniques that might be useful to you. With visual studio you can prevent your code from building until errors like this are resolved.
You could always use a T4 template to generate a class with constants for the files which actually exist. This is similar to what the T4 MVC template does for scripts and contents of the /Content directory; it scans those directories when it is run, and creates constants.

Oop data structure advice

I am writing a log file decoder which should be capable of reading many different structures of files. My question is how best to represent this data. I am using C#, but am new to OOP.
An example:
The log files have a range of sensor values. One sensor reading can be called A, another B. Obviously, there are many more than 2 entry types.
In different log files, they could be stored either as ABABABABAB or AAAAABBBBB.
I was thinking of describing this as blocks of entries. So in the first case, a block would be 'AB', with 5 blocks. In the second case, the first block is 'A', read 5 times. This is followed by a block of 'B', read 5 times.
This is quite a simplification (there are actually 40 different types of log file, each with up to 40 sensor values in a block). No log has more than 300 blocks.
At the moment, I store all of this in a datatable. I have a column for each entry, with a property of how many to read. If this is set to -1, it continues to the next column in the block. If not, it will assume that it has reached the end of the block.
This all seems quite clumsy. Can anyone suggest a better way of doing this?
I think you should first start here, and then here to learn a little bit about what object oriented programming is. Don't worry about your current problem while learning about OOP.
As you are learning about OO concepts, you should begin to understand code is not data, and data is not code. It does not matter how you represent your data from an OOP stance. You can write OO code to consume your data, or you could write procedurage code to consume your data, that part is irrelevant to the format of the data.
So then getting back to your question
My question is how best to represent this data
It depends on your needs. What is writing the log file? Do you have control over the writer and reader? If I did I would rely on build the built in serialization methods to minize the amount of code I need to write. Is the log file going to be really long? If so the "datatable" approach you described is usually better. If the log file isn't going to be a huge in file size, XML is really easy to work with.
Very basic and straightforward:
Define an interface for IEnrty with properties like string EntryBlock, int Count
Define a class which represents an Entry and implements IEntry
Code which doing a binary serialization should be aware of interfaces, for instance it should reffer IEnumerable<IEntry>
Class Entry could override ToString() to return something like [ABAB-2], surely if this is would be helpful whilst serialization
Interface IEntry could provide method void CreateFromRawString(string rawDataFromLog) if it would be helpful, decide yourself
If you want more info please share code you are using for serialization/deserializaton
In addition to what Bob has offered, I highly recommend Head First Design Patterns as a gentle, but robust introduction to OO for a C# programmer. The samples are in Java, which translate easily to C#.
As for OOP, you want to learn SOLID.
I would suggest you build this using Test Driven Development.
Start small, with a simple fragment of your log data and write a test like (you'll find a better way to do this with experience and apply it to your situation):
[Test]
public void ReadSequence_FiveA_ReturnsProperList()
{
// Arrange
string sequenceStub = "AAAAA";
// Act
MyFileDecoder decoder = new MyFileDecoder();
List<string> results = decoder.ReadSequence(sequenceStub);
// Assert
Assert.AreEqual(5, results.Count);
Assert.AreEqual("A", results[0]);
}
That test code snippet is just a starting point, and I've tried to be rather verbose in the assertions. You can come up with more creative ways over time. The point is to start small. Once this test passes, add another test where you mix "AB" and change your decoder to handle this properly. Eventually, you'll have a large set of tests that handle your different formats. Using TDD, you'll be on the path to using SOLID properly. Whenever you find something you can't test, you should review the rules and see if you can't make it simpler and inject dependencies.
Eventually you'll get into mocking. For example, you might find that you'd rather INJECT the ability for your MyFileDecoder class to have a dependency that will read your log file. In that case, you would create a mock object and pass that into the constructor and set the mock to return the sequenceStub when a method is called.

We have a graphical designer, now they want a text based designer. Suggestions?

I'm sorry I could not think of a better title.
The problem is the following:
For our customer we have created (as part of a larger application) a
graphical designer which they can use to build "scenario's".
These scenario's consist of "Composites" which in turn consist
of "Commands". These command objects all derive from CommandBase and
implement an interface called ICompilable.
The scenario class also implements ICompilable. When Compile() is called
on a command an array of bytes is returned which can then be send to the device
for which they are intended (can't disclose to much info about that hardware, sorry)
Just to give you an idea:
var scenario = new Scenario();
scenario.Add(new DelayCommand(1));
scenario.Add(new CountWithValueCommand(1,ActionEnum.Add,1));
scenario.Add(new DirectPowerCommand(23,false,150));
scenario.Add(new WaitCommand(3));
scenario.Add(new DirectPowerCommand(23,false,150));
scenario.Add(new SkipIfCommand(1,OperatorEnum.SmallerThan,10));
scenario.Add(new JumpCommand(2));
byte[] compiledData = scenario.Compile();
The graphical designer abstracts all this from the user and allows
him (or her) to simply drag en drop composites onto the designer surface.
(Composites can group commands so we can provide building blocks for returning tasks)
Recently our customer came to us and said, "well the designer is really cool,
but we have some people who would rather have some kind of programming language,
just something simple."
(Simple to them of course)
I would very much like to provide them with a simple language,
that can call various commmands and also replace SkipIfCommand with
a nicer structure, etc...
I have no idea where to start or what my options are (without breaking what we have)
I have heard about people embedding languages such as Python,
people writing their own language an parsers, etc...
Any suggestions?
PS: Users only work with composites, never with commands.
Composites are loaded dynamically at runtime (along with their graphical designer)
and may be provided by third parties in seperate assemblies.
From what i think i've understood you have two options
you could either use an XML style "markup" to let them define entities and their groupings, but that may not be best.
Your alternatives are yes, yoou could embedd a language, but do you really need to, wouldnt that be overkill, and how can you control it?
If you only need really simple syntax then perhaps write your own language. Its actually not that hard to create a simple interpreter, as long as you have a strict, unambiguous language. Have a look for some examples of compilers in whatever youre using, c#?
I wrote a very simple interperter in java at uni, it wasnt as hard as you'd think.
If you really just want a dirt simple language, you want a 'recursive descent parser'.
For example, a language like this:
SCENARIO MyScenario
DELAY 1
COUNT 1 ADD 1
DIRECT_POWER 23, False, 150
WAIT 3
...
END_SCENARIO
You might have a grammar like:
scenario :: 'SCENARIO' label newline _cmds END_SCENARIO
cmds:: _delay or _count or _direct_power or...
delay:: 'DELAY' number
Which gives code like:
def scenario():
match_word('SCENARIO')
scenario_name = match_label()
emit('var scenario = new Scenario();')
cmds()
match_word('END_SCENARIO')
emit('byte[] ' + scenario_name + ' = scenario.Compile();')
def delay():
match_word('DELAY')
length = match_number()
emit('scenario.Add(new DelayCommand('+ length +'))')
def cmds():
word = peek_next_word()
if word == 'DELAY':
delay()
elif ...
This looks like a perfect scenario for a simple DSL. See http://msdn.microsoft.com/en-us/library/bb126235(VS.80).aspx for some information.
You could also use a scripting language such as lua.Net.
Here's a Pythonic solution for building a DSL that you can use to compile and create byte code arrays.
Write a simple module that makes your C# structures available to Python. The goal is to define each C# class that users are allowed to work with (Composites or Commands or whatever) as a Python class.
Usually, this involves implementing a minimal set of methods with different conversions from C# types to native Python types and vice versa.
Write some nice demos showing how to use these Python class definitions to create their scripts. You should be able to create things like this in Python.
import * from someInterfaceModule
scenario= Scenario(
Delay(1),
Repeat( Range(10),
DirectPower( 23, False, 150),
Wait(3),
DirectPower( 23, False, 150)
)
)
scenario.compile()
These are relatively simple classes to define. Each class here be reasonably easy to implement as Python modules that directly call your base C# modules.
The syntax is pure Python with no additional parsing or lexical scanning required.
To add to S.Lott's comment, here's how you eval a Python script from C#
While it might be great fun to create this mini-language and code it all up, the real questions you need to ask are:
What is the business case for adding this feature / facility?
Who is going to pay for this feature?
Who is going to "sign off" on this feature if you build it?
"Really neat" features have a way of getting built when the reality might indicate the true answer to such a request is "no".
See if you have a stakeholder willing to sponsor this before proceeding. Then check with the end users to see what they really want before committing to the project.
Cheers,
-R

Categories