I have a question regarding inheritance, so I will describe the scenario below:
I am reading a text file containing logs. (One log per line)
Each log-line will have the following format:
"Date Type Description"
However, depending on the "Type" of log, I will have to parse the "Description" differently and pull out different fields.
Here are some examples:
5/1/2011 Information Field1, Field2, Field3
5/2/2011 Error Field1
--
So, what I tried to do was this:
-Get a line out of the log
-Parse it according to the pattern "Date Type Description"
-Look at the "Type" field, and create new objects/parse description as necessary
public class Log
{
public DateTime Date;
public String Type;
public String Description;
public Log(String line)
{
this.Date = GetDate();
this.Type = GetType();
this.Description = GetDescription();
}
}
public class InformationLog : Log
{
public String Field1;
public String Field2;
public String Field3;
public InformationLog(Log log)
{
this.Field1 = GetField1(log.Description);
this.Field1 = GetField2(log.Description);
this.Field1 = GetField3(log.Description);
}
}
public class Client
{
public void Main()
{
String line = ReadFileAndGetLine(); // Get a line from the file
Log log = new Log(line);
if(log.Type == "Information")
log = new InformationLog(log); // Is this right?
}
}
This works how I want it to, but it seems like this cannot be a good practice. The "log" variable is using itself as a parameter to its own constructor.
My question is:
Is there a standard way of doing this? Or, is there anything wrong with this implemenation?
--
Edit:
Also, I should mention: My reasoning was that I would parse the line once to get out the date and type, and then parse it again to get the finer details.
I decided to use inheritance so I wouldn't have to parse out the Date and Type fields twice.
Try to use Factory pattern
static class LogFactory
{
public static Log Create(String line)
{
if(GetType(line) == "Information")
return CreateInformationLog(line);
return CreateLog(line);
}
private static Log CreateLog(String line)
{
return new Log(line);
}
private static Log CreateInformationLog(String line)
{
return new InformationLog(line);
}
}
And then try to use
String line = ReadFileAndGetLine(); // Get a line from the file
Log log = LogFactory.Create(line);
As per my comment, why not just do something a little like this:
public enum LogEntryType
{
Error = -1,
Information = 0,
}
public class LogEntry
{
public string Raw;
public DateTime Date;
public LogEntryType Type;
public string Description;
public LogEntry(String line)
{
Raw = line;
Date = ParseDate();
Type = ParseType();
Description = ParseDescription();
}
public string ParseDescription()
{
var result = string.Empty;
switch(Type)
{
case LogEntryType.Error:
//parse here
break;
case LogEntryType.Information:
//parse here
break;
}
return result;
}
}
I notice you have fields in the derivative class, but the description could be parsed here; though, I can see why people may want to shift it to the place that actually knows how the description should be parsed, in which case you could use a factory pattern suggested in another answer, or implement a 'property bag' type scenario - but drifting away from strong typing is generally frowned upon these days, I reckon.
Another suggestion, though very similar to your initial attempt, tends to encapsulate management of the types, as opposed to having a detached class handle such stuff - a pattern a little (superficially) like Exception where you have a root entry and inner entries:
public enum LogEntryType
{
Error = -1,
Information = 0,
}
public class LogEntry
{
public string Raw;
public DateTime Date;
public LogEntryType Type;
public string Description;
public InnerLogEntry InnerEntry;
public LogEntry(String line)
{
Raw = line;
Date = ParseDate();
Type = ParseType();
//parse the 'raw' description...
Description = ParseDescription();
//determine the inner entry type...
switch (Type)
{
case LogEntryType.Error:
InnerEntry = new ErrorLogEntry(this);
break;
case LogEntryType.Information:
InnerEntry = new InformationLogEntry(this);
break;
}
}
}
public abstract class InnerLogEntry
{
protected LogEntry Parent;
public InnerLogEntry(LogEntry logEntry)
{
Parent = logEntry;
}
}
public class InformationLogEntry : InnerLogEntry
{
public InformationLogEntry(LogEntry logEntry)
: base(logEntry)
{
//parse custom data
}
}
public class ErrorLogEntry : InnerLogEntry
{
public ErrorLogEntry(LogEntry logEntry)
: base(logEntry)
{
//parse custom data
}
}
Related
I'm creating a program to generate schematics based off of user input. This has to be done dynamically/by hand due to the sheer volume of different possibilities (6.8M, growing exponentially). Right now I'm working on importing some data via CSV.
Example data:
Type,TIN_pos,TIN_ID,Desc
Elect, 0, X, Manual Regulator
Elect, 0, A, Electronic Regulator
Import code:
List<TIN_Fields> values = File.ReadAllLines("C:\\Users\\User\\Desktop\\Visual Basic\\CSV_Test_1.csv")
.Skip(1)
.Select(v => TIN_Fields.FromCsv(v))
.ToList();
public class TIN_Fields
{
public string Type;
public int TIN_pos;
public string TIN_ID;
public string Desc;
public static TIN_Fields FromCsv(string csvLine)
{
string[] values = csvLine.Split(',');
TIN_Fields _Fields = new TIN_Fields();
_Fields.Type = Convert.ToString(values[0]);
_Fields.TIN_pos = Convert.ToInt16(values[1]);
_Fields.TIN_ID = Convert.ToString(values[2]);
_Fields.Desc = Convert.ToString(values[3]);
return _Fields;
}
}
Once that data is Imported, I need to do two things with it,
display the raw csv data in a ListView table, just so users can see if anything in the list needs updating.
be able to compare the items in the list to various characters in a 10-digit hexadecimal code, and spit out some results.
First and foremost, i need to run through the list that was created with the above code, make sure that:
TIN_pos value = 0
because that is the character position of the input box.
Then, with the remaining options, look for the character represented in the input in the TIN_ID field.
Once found, it should then output the Desc field.
Everywhere I have looked says to use foreach, but that requires the array name, which is the part that is confusing me. I've tried filling in basically all of the variables in the FromCSV Method and usually get an error that the class doesn't have a definition.
to hopefully clear up confusion with my explanation, here is the code I created that does the same thing, but with the CSV data hard coded into it, using switch cases and if statements.
public partial class Form1 : Form
{
public string Model_Chassis;
public string Model_Test_Type;
public int ChannelNumberVar => Convert.ToInt32(TextBox_TIN[2]);
public string Tester_Type_Selector;
public string TextBox_TIN
{
get { return TIN_Entry_TextBox.Text; }
set { TIN_Entry_TextBox.Text = value; }
}
public string Model_Data_D
{
get { return Model_Data.Text; }
set { Model_Data.Text = value; }
}
public Form1()
{
InitializeComponent();
}
//Method grabs TIN Box data and decodes it to model information.
public void Model_Select()
{
//Picks Model Chassis
switch (char.ToUpper(TextBox_TIN[0]))
{
case 'H':
{
Model_Chassis = Coding.Model1.description;
}
break;
default:
{
Model_Data_D = "INVALID TIN";
}
break;
}
//Picks Test Type
switch (char.ToUpper(TextBox_TIN[3]))
{
case '0':
{
Model_Test_Type = Test_Types.TT_PD.TT_tt;
}
break;
case '1':
{
Model_Test_Type = Test_Types.TT_PV.TT_tt;
}
break;
default:
{
Model_Test_Type = "";
}
break;
}
//Puts chassis and Test Type together
if (Model_Data_D.Equals("INVALID TIN"))
{
;
}
else if (char.ToUpper(TextBox_TIN[2]).Equals(Coding.Num_Chan_1_2.tin_id))
{
Model_Data_D = $"{Model_Chassis}-{Model_Test_Type}";
}
else
{
Model_Data_D = $"{Model_Chassis}-{TextBox_TIN[2]}{Model_Test_Type}";
}
}
public class Coding
{
public char tin_id;
public string description;
public Coding(char TIN_ID, string Desc)
{
tin_id = TIN_ID;
description = Desc;
}
public static Coding Model1 = new Coding('H', "Model1");
public static Coding Num_Chan_1_2 = new Coding('X', "Single Channel");
public static Coding Elect_Reg_F_1 = new Coding('X', "Manual Regulator");
}
}
INPUT:
HXX0X
OUTPUT
Model1-PD
Thanks in advance for the help!
You're asking quite a few questions, and providing a lot of extra details in here, but for this:
"First and foremost, i need to run through the list that was created with the above code, make sure that:
TIN_pos value = 0
because that is the character position of the input box."
(seeing as you say you need to do this 'first and foremost').
In your FromCsv method, check the value as you create the record, and throw an error if it is invalid. Like this:
public static TIN_Fields FromCsv(string csvLine)
{
string[] values = csvLine.Split(',');
TIN_Fields _Fields = new TIN_Fields();
_Fields.Type = Convert.ToString(values[0]);
_Fields.TIN_pos = Convert.ToInt16(values[1]);
if(_Fields.TIN_pos != 0){
throw new Exception("TIN_pos must be 0");
}
_Fields.TIN_ID = Convert.ToString(values[2]);
_Fields.Desc = Convert.ToString(values[3]);
return _Fields;
}
Assuming you've read in your CSV correctly, which it seems you have, then selecting the appropriate TIN from the list is a simple LINQ statement. The following code assumes that TIN IDs are unique and only a single character in length.
static void Main(string[] args)
{
string testCsv = #"C:\Users\User\Desktop\Visual Basic\CSV_Test_1.csv";
List<TIN_Fields> values = File.ReadAllLines(testCsv)
.Skip(1)
.Select(v => TIN_Fields.FromCsv(v))
.ToList();
// Simulates input received from form
string input = "HXX0X";
TIN_Fields selectedTIN = values.First(x => x.TIN_ID == Convert.ToString(input[0]));
// Insert the description as needed in your ouput.
string output = $"{ selectedTIN.Desc }-";
}
Hopefully that answers another part of the problem. The Convert.ToString() is required because the output of input[0] is a char.
So I have this simple (for others) exercise where i need to create a pharmacy and add to that 2 types of drugs. I have one class called Drugs which contains the attributes of the drugs:
public class drugattr
{
public int id;
public string drugName;
public string DrugDesc;
public int drugIntensity ;
public drugattr(int id, string drugName, string DrugDesc, int drugIntensity)
{
this.id = id;
this.drugName= drugName;
this.DrugDesc = DrugDesc;
this.drugIntensity = drugIntensity ;
}
}
Then i have a pharmacy class with the pharmacies attributes:
public class pharmacyatrr
{
public string PharmacyName;
public string PharmacyTown;
public List<drugattr> Atrributes= null; // the list with the drugs' attributes
public pharmacyatrr(string pharmacyName, string pharmacyTown, List<drugattr> atrributes)
{
this.PharmacyName = pharmacyName;
this.PharmacyTown = pharmacyTown;
this.Atrributes = atrributes;
}
and i have my main class where i need to create a pharmacy and assign to it a couple of drugs.
public class Program : pharmacyatrr
{
public Program(string PharmacyName, string PharmacyTown , List<drugattr> Atrributes) : base(PharmacyName, PharmacyTown , Atrributes)
{
this.PharmacyName = pharmacyName;
this.PharmacyTown = pharmacyTown;
this.Atrributes = atrributes;
}
static void Main(string[] args)
{
drugattr drugA = new drugattr(1, "DrugA_Name", "Very STrong", 20);
drugattr drugB = new drugattr(2, "DrugB_Name", "Mild Strong", 8);
pharmacyatrr pharmacy1 = new pharmacyatrr("PharmacyName", "Town", drugA); // the problem is here
}
}
So if I try to add drugB i get the expected error that it can only accept 3 parameters.
If i create a pharmacy2 with the same name and town but with drugB that wouldn't create a new pharmacy?
I need one pharmacy to have multiple drug entries...
any tips on how to solve this? I am fairly new to C# and programming so please don't go harsh on me!
This should work. Pretty much what everyone has said, but just the complete code.
Drugs Class
class DrugAttribute
{
public int id;
public string drugName;
public string drugDescription;
public int drugIntensity;
public DrugAttribute(int id, string drugName, string drugDescription, int drugIntensity)
{
this.id = id;
this.drugName = drugName;
this.drugDescription = drugDescription;
this.drugIntensity = drugIntensity;
}
}
And the Pharmacy Class
class PharmacyAtrribute
{
public string pharmacyName;
public string pharmacyTown;
public List<DrugAttribute> drugList = null;
public PharmacyAtrribute(string pharmacyName, string pharmacyTown, List<DrugAttribute> drugList)
{
this.pharmacyName = pharmacyName;
this.pharmacyTown = pharmacyTown;
this.drugList = new List<DrugAttribute>(drugList);
}
}
And the main class
class Program : PharmacyAtrribute
{
public Program(string pharmacyName, string pharmacyTown, List<DrugAttribute> drugList) : base(pharmacyName, pharmacyTown, drugList)
{
this.pharmacyName = pharmacyName;
this.pharmacyTown = pharmacyTown;
this.drugList = new List<DrugAttribute>(drugList);
}
static void Main(string[] args)
{
DrugAttribute drugA = new DrugAttribute(1, "DrugA_Name", "Very Strong", 20);
DrugAttribute drugB = new DrugAttribute(2, "DrugB_Name", "Mild Strong", 8);
List<DrugAttribute> listOfDrugs = new List<DrugAttribute>{ drugA, drugB };
PharmacyAtrribute pharmacy1 = new PharmacyAtrribute("PharmacyName", "Town", listOfDrugs);
}
}
I'm sure you may have noticed I changed some of the names. I'll just give you a couple of helpful tips regarding naming conventions. For Classnames, Microsoft encourages use of the Pascal capitalization style. So in your case, drugattr would be DrugAttr. For variables and attributes, Camel Case is encouraged. So
public string PharmacyName;
public string PharmacyTown;
public List<drugattr> Atrributes= null;
should become
public string pharmacyName;
public string pharmacyTown;
public List<drugattr> atrributes= null;
For more about naming conventions, have a look at this https://msdn.microsoft.com/en-us/library/x2dbyw72(v=vs.71).aspx
And with names, it's good to be as descriptive as possible, so calling your class DrugAttributes might be a good idea. Anyone who is reading your code will know exactly what it's about even without comments (Although comments are a must too).
Even if it's just a simple learning exercise, it's always good to practice with conventional styles.
You need to create a list of drugs to match your List parameter in the pharmacyattr constructor.
Create a new list like:
List<drugattr> drugList = new List<drugattr>();
And add to the list like this:
drugList.Add(drugA);
You can then create your pharmacy with the slight adjustment of:
pharmacyatrr pharmacy1 = new pharmacyatrr("PharmacyName", "Town", drugList);
var drugs = new List<drugattr> { drugA, drugB };
pharmacyatrr pharmacy1 = new pharmacyatrr("PharmacyName", "Town", drugs);
I am building a model with Entity Framework and purchased responsive CSS.
The built in fixed icons comes with CSS. Like as follows (Name and Icon Class Value)
I need a way to keep the names of icons as fixed enums to access it from the VS intellisense. Currently we can't store as a entity table in entity framework (as it require relationship with tables difficult to maintain) and enum doesn't allows string type.
Code that did not work:
public sealed class IconType
{
public static readonly IconType Rupee_Icon = new IconType("rupee-icons");
public static readonly IconType Doller_Icon = new IconType("doller-icon");
private IconType(int EnumID,string EnumObjectValue)
{
IconValue = EnumObjectValue;
}
public string IconValue { get; private set; }
}
More code that did not work (CSS class names contains whitespaces like ui bell icon):
public enum Icon
{
NotSet=0,
Idea Icon=1,
Bell Icon =2
}
Is there any other ways to use names / objects as enums or constants in EF for easy intellisense in Visual Studio?
You could:
Omit the white spaces in the enums:
public enum Icon
{
NotSet = 0,
IdeaIcon = 1,
BellIcon = 2
}
Add a description or name (Or even some custom attribute) attributes to the enums:
public enum Icon
{
NotSet = 0,
[Description("ui idea icon")]
IdeaIcon = 1,
[Description("ui bell icon")]
BellIcon = 2
}
When needed get the description name. Example method to get the description attribute value:
public static string GetDescription<T>(this T enumerationValue)
where T : struct, IConvertible
{
var type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
// Tries to find a DescriptionAttribute for a potential friendly name for the enum
var memberInfo = type.GetMember(enumerationValue.ToString(CultureInfo.InvariantCulture));
if (memberInfo.Length > 0)
{
var attributes = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
// Pull out the description value
return ((DescriptionAttribute)attributes[0]).Description;
}
}
// If we have no description attribute, just return the ToString of the enum
return enumerationValue.ToString(CultureInfo.InvariantCulture);
}
Did you consider using string constants?
public static class IconType
{
public const string RUPEE_ICON = "rupee-icon";
public const string DOLLER_ICON = "doller-icon";
// ...
}
Store the icon's as plain old objects. Why make use of entity framework at all?
public static class Icons
{
public enum Type
{
IdeaIcon = 1,
BellIcon =2
}
public static Icon Get(Type type)
{
return IconCollection.Single(icon => icon.Type == type);
}
static IEnumerable<Icon> IconCollection
{
get
{
return new List<Icon>
{
new Icon(Type.IdeaIcon, "Idea Icon", "icon idea-icon"),
new Icon(Type.BellIcon, "Bell Icon", "icon bell-icon"),
};
}
}
public class Icon
{
public Icon(Type type, string description, string cssClass)
{
Type = type;
Description = description;
CssClass = cssClass;
}
public Type Type { get; private set; }
public string Description { get; private set; }
public string CssClass { get; private set; }
}
}
Use in code:
public class Class1
{
public void Method1()
{
var ideaIcon = Icons.Get(Icons.Type.IdeaIcon);
var x = ideaIcon.CssClass;
var y = ideaIcon.Description;
var bellIcon = Icons.Get(Icons.Type.BellIcon);
// etc...
}
}
Razor view:
#Icons.Get(Icons.Type.BellIcon).CssClass
If you needed to enumerate over the icon collection you could easily add another static accessor to the Icons class.
I've build some classes as per instructed in the following answer here in order to be able to serialize a list of generic objects; such as instances of KeyValuePair and KeyValuePair.
Unfortunately, it appears that the .proto file generated by the GetProto() method does not generate a file that can be parsed properly for C++. Subtype messages generated for arrays are suffixed with "[]". The protoc.exe chokes on the "[]" when compiling for C++.
Since the message names seem to be arbitrary for protobuf (that is, they're not actually included in the data stream), is possible to tell protobuf-net to use "_Array" instead of "[]" when naming the sub-types? Or is there some other avenue I should take so that the .proto file generated can be consumed by a C++ application?
Thanks,
Below is the relevant code and generated proto file.
The base class is:
[DataContract]
[ProtoInclude(101, typeof(KeyValuePairResponse<string>))]
[ProtoInclude(102, typeof(KeyValuePairResponse<int>))]
[ProtoInclude(103, typeof(KeyValuePairResponse<double>))]
[ProtoInclude(111, typeof(KeyValuePairResponse<string[]>))]
[ProtoInclude(112, typeof(KeyValuePairResponse<int[]>))]
[ProtoInclude(113, typeof(KeyValuePairResponse<double[]>))]
public abstract class KeyValuePairResponse
{
protected KeyValuePairResponse() { }
[DataMember(Order = 1, IsRequired = true)]
public string Key { get; set; }
public object Value
{
get
{
return this.ValueImplementation;
}
set
{
this.ValueImplementation = value;
}
}
protected abstract object ValueImplementation { get; set; }
public static KeyValuePairResponse<T> Create<T>(string key, T value)
{
return new KeyValuePairResponse<T>(key, value);
}
}
and the generic class is:
[DataContract]
public sealed class KeyValuePairResponse<T> : KeyValuePairResponse
{
public KeyValuePairResponse()
{
}
public KeyValuePairResponse(string key, T value)
{
this.Key = key;
this.Value = value;
}
[DataMember(Order = 2, IsRequired = true)]
public new T Value { get; set; }
protected override object ValueImplementation
{
get
{
return this.Value;
}
set
{
this.Value = (T)value;
}
}
}
The .proto file that GetProto<KeyValuePairResponse>() creates looks like:
message KeyValuePairResponse {
required string Key = 1;
// the following represent sub-types; at most 1 should have a value
optional KeyValuePairResponse_String KeyValuePairResponse_String = 101;
optional KeyValuePairResponse_Int32 KeyValuePairResponse_Int32 = 102;
optional KeyValuePairResponse_Double KeyValuePairResponse_Double = 103;
optional KeyValuePairResponse_String[] KeyValuePairResponse_String[] = 111;
optional KeyValuePairResponse_Int32[] KeyValuePairResponse_Int32[] = 112;
optional KeyValuePairResponse_Double[] KeyValuePairResponse_Double[] = 113;
}
message KeyValuePairResponse_Double {
required double Value = 2 [default = 0];
}
message KeyValuePairResponse_Double[] {
repeated double Value = 2;
}
message KeyValuePairResponse_Int32 {
required int32 Value = 2 [default = 0];
}
message KeyValuePairResponse_Int32[] {
repeated int32 Value = 2;
}
message KeyValuePairResponse_String {
required string Value = 2;
}
message KeyValuePairResponse_String[] {
repeated string Value = 2;
}
This is simply a bug in GetProto. I suggest logging it on the github protobuf-net list, or even submitting a pull request if you're feeling adventurous.
For now: Ctrl+h (find and replace) is probably your friend.
I want to retrieve data from a list I created that contains class objects via a foreach but I'm not able to.
Can somebody please tell me what's missing in my code?
I have a class Recipes.cs that contains the following code:
public class Recipe
{
string _oveskrift;
int _recipe_id;
string _opskrift;
int _kcal;
public Recipe(string overskrift, int recipe_id, string opskrift,int kcal)
{
_oveskrift = overskrift;
_recipe_id = recipe_id;
_opskrift = opskrift;
_kcal = kcal;
}
}
public class Recipes
{
public List<Recipe> CreateRecipeList()
{
Recipe opskrift1 = new Recipe("Cornflakes med Chili",1,"4 kg cornflakes bages", 420);
Recipe opskrift2 = new Recipe("Oksemørbrad",2,"Oksemørbrad steges i baconfedt", 680);
Recipe opskrift3 = new Recipe("Tun i vand",3,"Dåsen åbnes og tunen spises", 120);
List<Recipe> Recipelist = new List<Recipe>();
Recipelist.Add(opskrift1);
Recipelist.Add(opskrift2);
Recipelist.Add(opskrift3);
return Recipelist;
}
}
I call CreateRecipeList() from another class calculator.cs and the code looks like this:
private int FindRecipes()
{
List<Recipe> Rlist = new List<Recipe>();
// CREATE THE CLASS AND ADD DATA TO THE LIST
Recipes r = new Recipes();
Rlist = r.CreateRecipeList();
int test = 0; // used only for test purposes
foreach(var rec in Rlist)
{
rec.????
test++;
}
return test;
}
I would presume that I should be able to dot my way into rec."the class object name"."the value"
But nothing happens!.
All I get is the option to rec.Equals, rec.GetHashcod ect. which is clearly wrong.
For the record I have also tried:
foreach(Recipe rec in Rlist)
{
rec.????
test++;
}
But that doesn't work either.
The Int test are only there for test purposes.. and it return 3.. so the list does contain the correct information.
Please show us the code for the Recipe class. Besides that, you're most of the way there...
foreach(Recipe rec in Rlist)
{
string str = rec.<PropertyName>;
}
You need to set the proper access modifiers for the members in your Recipe class.
public : Access is not restricted.
protected : Access is limited to the containing class or types derived from the containing class.
Internal : Access is limited to the current assembly.
protected internal: Access is limited to the current assembly or types derived from the containing class.
private : Access is limited to the containing type.
By default, the members of your Recipe class will have the private access modifier.
string _oveskrift;
int _recipe_id;
string _opskrift;
int _kcal;
is:
private string _oveskrift;
private int _recipe_id;
private string _opskrift;
private int _kcal;
Maybe you want to modify your member access as follows, in order to set the values of the members only inside the class code. Any attempt to set their values outside the Recipe class will fail, as the set is private. The get remains public, which makes the value available for reading.
public class Recipe
{
string _oveskrift;
int _recipe_id;
string _opskrift;
int _kcal;
public string Oveskrift
{
get
{
return _oveskrift;
}
private set
{
_oveskrift=value;
}
}
public int RecipeId
{
get
{
return _recipe_id;
}
private set
{
_recipe_id = value;
}
}
public string Opskrift
{
get
{
return _opskrift;
}
private set
{
_opskrift = value;
}
}
public int Kcal
{
get
{
return _kcal;
}
private set
{
_kcal = value;
}
}
public Recipe(string overskrift, int recipe_id, string opskrift, int kcal)
{
_oveskrift = overskrift;
_recipe_id = recipe_id;
_opskrift = opskrift;
_kcal = kcal;
}
}
Also, please read as soon as possible the following MSDN article: Capitalization Conventions. And also, this one: C# Coding Conventions (C# Programming Guide).