C# type design Question [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
This might sound a little stupid but I am still curious about what the community thinks.
So I have a WebService returning a UpdateInfo class.
Now consider the following definitions
public enum TTCFileType
{
API = 0,
BOOKMARK,
TICKMARK
}
public class FileUpdateInfo
{
public string FileName;
public string FileDownLoadURI;
public TTCFileType FileType;
}
public class UpdateInfo
{
public FileUpdateInfo fuInfo;
//Other
}
Here is the issue, if the TTCFileType has the value TICKMARK then I need another enum viz Tickmark Type( the biz logic demands this information). I am wondering what is the best way to represent that. I dont want a method signature where I have something Like
UpdateMethod( UpdateInfo ui, TickMarkType tt)
where I examine tt if ui.fuInfo.FileType == TTCFileType.TICKMARK
I guess I am trying to find an semi elegant way at least to represent the conditional requirement for getting the second piece of information out ( in many ways this so reminds of VARIANTS , if var.VT == VT_[thingy] then use vt.[thingy] and yes I know how c# developers feel about unions :-)
Anyway curious if there is a nifty way to do this
Thanks

Just include TickMarkType field to FileUpdateInfo class?

I'd be tempted to go with something like:
public enum TTCFileType
{
API = 0,
BOOKMARK,
TICKMARK_TYPE1 = 100,
TICKMARK_TYPE2 = 101,
TICKMARK_TYPE3 = 102
}
and so on. Depending on how many there are and how manageable it would feel within the wider context of your code.

Ideally, you need two additional structure(s)
public enum TickmarkType
{
TYPE1=0,
TYPE2
}
public class TickMarkFileUpdateInfo : FileUpdateInfo
{
public TickmarkType type;
}
And then read about polymorphism in web services

Store the enum value as an int. Add some offset to the value for your second enum (e.g., 1000) so that if the value is from the first enum it's 0..2 and if it's from the second enum it's 1000.1010 or whatever. Then you can set 2 properties, one that returns a nullable TTCFileType and the other that returns a nullable TickType, to read and write the values into the int field.

It seems like you're trying to use only data structures, when using OO features (such as inheritance) might help you. Maybe this example code gives you some ideas:
public class Update
{
// ... ?
}
public class FileUpdate : Update
{
public virtual string Name { get; set; }
public virtual string DownloadUri { get; set; }
public virtual bool IsTickMarked { get; set; }
}
public class ApiFileUpdate : FileUpdate
{
// ...
}
public class BookmarkFileUpdate : FileUpdate
{
// ...
}
You can still serialize these, given the proper serialization attributes.
In fact, you can define (potentially virtual) methods on these various classes, and actually use them to implement your program.
Overly segregating your data and code is known as the Anemic Domain Model Anti-Pattern.

Related

Is there a good practice of setting default values in an constructor? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Consider a simple class
public class MyClass
{
private int myProperty
...
public int MyProperty
{
get
{
return myProperty;
}
set
{
// some evaluation/condition
myProperty= value;
}
}
...
}
Now, if I want to create an empty constructor where I set default values for the class properties I could do this either this way:
public MyClass()
{
myProperty = 1;
...
}
or this way:
public MyClass()
{
MyProperty = 1;
...
}
Both examples seem valid, since I would never set a default value, that doesn't meet the requirements in the setter evaluation.
The question is, is there a best practice or doesn't it matter anyway?
What would be the advantage of one or the other be (as I can't find any)? Is there some reference, where this question is adressed?
So far I have come across code from many different developers that use either or both ways...
You can use both. But i prefer the first one. Why? Because the value that the property uses is directly assigned. For C# 6 above, you can use default value in a property directly without using constructor.
public class Person
{
public string FirstName { get; set; } = "<first_name>";
public string LastName { get; set; } = "<last_name">;
}
I personally like to set it as you done in first block.
For me it serve as additional fact of method is constructing object, not using alredy constructed. Also it makes me sure that properties is not called (they transform to set/get functions which results in couple of excess instruction).
But i believe that both variants are valid and maybe compiler optimizes properties to direct assignment.
For simple data first method is ok. But on more complex data, you could have a condition in the set (depending to another variable for example, set { if (Config.TestEnv) ...} so if you directly set the private value, you could be in trouble.

Is Enum Right For This? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm working on a Model and am using enum for a list of named items.
class Verse
{
public int Number { get; set; }
public string Text { get; set; }
}
class Chapter
{
public int Number { get; set; }
public List<Verse> Verses { get; set; }
}
class Book
{
public string Name { get; set; }
public List<Chapter> Chapters { get; set; }
}
class Bible
{
public Versions Version { get; set; }
public List<Book> Books { get; set; }
}
enum Versions
{
asv1901,
bbe,
darby,
kjv,
nasb,
niv,
nkjv,
nlt,
rsv,
web,
ylt
}
That seemed like a logical way to do it, but I'm finding that working with enum is adding unnecessary difficulty.
foreach (var chapter in chapters)
{
var bibleitem = new Bible();
bibleitem.Version = (Versions)Enum.Parse(typeof(Versions), chapter.version);
}
Would it make more sense to just use string[] or something? I'm sure there is some added benefit, to enum, but I question my benefit.
The guidance from Microsoft is here:
https://msdn.microsoft.com/en-us/library/ms229058%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396
In particular note: Do not use an enumeration for open sets
People write new Bibles all the time, so your set of enumerated values could change. You would be better off using string constants, for instance, where you could add more at will.
While we are at it, some additional critiques of your code.
class Verse
{
public int Number { get; set; }
public string Text { get; set; }
}
Why is this a class, and why are the properties settable? Do you envision having an existing Verse in hand, and wishing to change its number and text to something different? If not, then don't allow it. I would write this as
struct Verse
{
public int Number { get; private set; }
public string Text { get; private set; }
public Verse(int number, string text) : this()
{
this.Number = number;
this.Text = text;
}
}
Once it is created, it does not change. Also, this is a small immutable thing that is logically a value, so make it a struct.
class Chapter
{
public int Number { get; set; }
public List<Verse> Verses { get; set; }
}
Again, if you have an existing chapter, do you intend the set of verses to change? Because anyone can call Add on a list. Also, this constrains you to having the list available at all times, rather than computed lazily from a database. Make this IEnumerable<Verse>.
enum Versions
{
asv1901,
bbe,
This violates both naming guidelines and general legibility. Spell things out! AmericanStandardVersion1901 is far better than asv1901.
You should use enums when you have a named list of constants in your code and you know that this particular list is not gonna change over time (hence called names list of constants).
what benifits do you get?
READABILITY. Using enums increases the readability of your code. Consider the scenario where I have 2 employee types: Permanent and ContractBased. Now I can do this in my code like this:
if employee.Type == 1
// deal with permanent employee
else if employee.Type == 2
// deal with contract based employee here
such code is hard to read and maintain as no one could guess what employee.Type == 1 or what employee.Type == 2 means.
If I define an enum instead like this:
enum EmployeeType { Permanent=1, ContractBased=2 }
my code becomes like this:
if employee.Type == EmployeeType.Permanent
// deal with permanent employee
else if employee.Type == EmployeeType.ContractBased
// deal with contract based employee here
the readability of code gets maximized and also I have intellisense available.
The problem with strings:
1) you would end up having hard-coded string literals in your code
2) no intellisense
3) more memory consumption
how to deal with added complexity?
you should have an enum type variable for chapter.Version (which is right now missing) instead of int. that way you wouldnt need to do the parsing.
but I'm finding that working with enum is adding unnecessary difficulty.
it depends on your needs. if your set will not change enum is the best way to go as it adds a more control with a verbose description and limited set that cannot be bypassed when you work with many developers on the same project.
But
if your set can change during the development of the solution and you can't preview the set than a string would be the better way to go
Enums usually work best when:
No one adds or removes records to it anytime soon (hopefully never).
You don't need to use the real value behind your enum records.
You don't need to use the name of your records.
Enum.Parse can be used to get the enum record from a string, but as you noticed it's pretty ugly and I discourage you from using it. If you have the integral enum value you can simply perform a cast like this:
Versions version = (Versions)0;
But note that an enum is not guranteed to be of type int, it could also be any other integral value. int just happens to be the default. I do however also discourage you from relying on the enum's real integral value because something like this is also possible:
public enum Versions
{
One = 1,
Two = 2,
Three = 3
}
public void Do()
{
Versions version = (Version)-9;
// version is now Versions.One.
// Its value however is -9, what kind of version should -9 be?
}
The code above runs without errors because the runtime doesn't perform any checks on the value you are using for the cast.
The answer to your question depends on the nature of Versions. If you believe it will not be changed in the future then it is a good canditate for an enum in most cases. But you should use the enum everywhere across your application. I see in your sample that you are using the version as a string and therefore need to perform an ugly Enum.Parse. Consistency is an important factor when using enums, well it always is but it doesn't hurt to point it out again.
If you think your records are of a more dynamic nature you are probably best suited with strings. In that case you should use strings consistently. (Just wanted to point it out once again)
using the enum provides methods for comparing instances of this class, converting the value of an instance to its string representation, converting the string representation of a number to an instance of this class, and creating an instance of a specified enumeration and value.
Correcty using im class.
Exp.
public enum Versions
{
asv1901,
bbe,
darby,
kjv,
nasb,
niv,
nkjv,
nlt,
rsv,
web,
ylt
}
Next, implement
foreach (var chapter in chapters)
{
var bibleitem = new Bible();
bibleitem.Version = (Versions) "Your class enum"(typeof(Versions), chapter.version);
}
Enum and more used for good programming practices, clean code
Referency using enum: Enum Class Microsoft

Best way to send large amount of form data to an object [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a program I'm writing that has a form with around 15 inputs that describe a type of machine that we make (model, length, width, height, motor type, color, etc). There are 12 different models of this machine so I have a sub class "machine" and then 12 separate classes that inherit the "machine class". In my form, one of the inputs the user selects is the model. I'm trying to figure out a way to pass the 15 items to the specific "model" class fields without having to type it out 12 times with a case/switch (based on which model is selected). Is there a way to pass the inputs to the parent class and then when you figure out which specific class you need to create, reference the data that was stored in the parent class? I hope that makes sense what I'm saying. I'm struggling with describing the situation. If I can provide any more info please let me know!!
Thanks!
I would suggest you to write an interface, let's say something like IMachineModel with the required methods/properties. Write as many classes as models you have and implement the previously created interface.
Provide in each concrete class the logic required. Then you only need to instantiate the suitable class and use its properties and methods implemented from the interface.
Quick Example:
public class FirstConcreteMachineModel : IMachineModel
{
public string Model { get; set; }
public void DoSomething()
{
Console.WriteLine("I am a machine of type 1");
}
}
public class SecondConcreteMachineModel : IMachineModel
{
public string Model { get; set; }
public void DoSomething()
{
Console.WriteLine("I am a machine of type 2");
}
}
public class MachineModelFactory
{
public static IMachineModel CreateMachineModel(string type)
{
//switch with all possible types
switch (type)
{
case "one":
return new FirstConcreteMachineModel { Model = type };
case "two":
return new SecondConcreteMachineModel { Model = type };
default:
throw new ArgumentException("Machine type not supported");
}
}
}
Then you can use it like:
IMachineModel machine = MachineModelFactory.CreateMachineModel("two");
machine.DoSomething();
It would print
I am a machine of type 2.
To add to Areks's answer -- you could create a factory that given the inputs returns a class that implements IMachineModel .... Internally you have a number of options of how to determine the concrete class including your switch statement or chain of responsibility

C# design question [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I started designing a small application and have some architecture-related questions.
I have some basic entities, which I'm willing to model - Repository and Indicator.
Repository is basically a facade using the Repository Pattern, which is able to retrieve / store arbitrary entities using some database holder (right now it's NHibernate-driven, but I guess that's not actually important).
The Indicator may be called the logical core of my application. It is used to combine abstract values and the exact time at which that value was achieved (so it forms and operates on Value - Time pairs).
I am willing to make this Indicator as generic as possible, still I think my current solution is a big fail :)
See the following chunks of code:
public interface IIndicator<T>
{
IEnumerable<T> RetrieveValues(DateTime start, DateTime end);
}
// Should also have something like indicator wrapper / proxy stub here - anything
// that represents the 'IIndicator' interface acts through that proxy and
// caches the evaluated data using it.
This is a basic attempt to implement the indicator (right now this can actually be considered as a mock):
public class Indicator<TValue> :
// Self-referencing generic parameter.
IIndicator<Indicator<TValue>.TimestampProxy>
{
// Proxy, which is used to add the timestamp to
// every indicated value.
public class TimestampProxy
{
public TValue Value;
public DateTime Time;
public TimestampProxy(DateTime time, TValue value)
{
Time = time;
Value = value;
}
}
private readonly IRepository repository;
public Indicator(IRepository repository)
{
this.repository = repository;
}
public IEnumerable<TimestampProxy> RetrieveValues(DateTime start, DateTime end)
{
// Note the custom time stamp comparation in the lambda
// expression. Comparation includes the 'start' and 'end' limits.
IQueryable<TimestampProxy> queryable = repository.Retrieve<TimestampProxy>(
x => x.Time.CompareTo(start) >= 0 && x.Time.CompareTo(end) <= 0);
return queryable.ToList();
}
}
Now - this might look fine, but I'm absolutely sure that the TimestampProxy used is really evil.
It also makes the things hard to understand (for example, method signature IEnumerable<TimestampProxy> RetrieveValues(...) would probably result in a "wtf?!" phrase from a person who examines the code).
Unfortunately, I can't come up with a better solution / global redesign - could you advice me how to do it or simply tell some ideas about how this kind of feature should be done?
Thanks.
How about refactoring the RetrieveValues method back into the Repository itself and going with a much simpler Indicator class that basically replaces your TimestampProxy class.
public class Indicator<T>
{
public DateTime Timestamp { get; set; }
public T Value { get; set; }
}
public class Repository
{
public IEnumerable<Indicator<T>> RetrieveIndicators<T>( DateTime start, DateTime end )
{
// determine table to query based on type T
// query and convert objects to Indicator<T>
// return collection
}
}
One thing that bothers me is that in making it generic you've lost the connection to the DB table. It might be better to simply define an interface that all of your specific DB objects implement and use partial implementations to map the actual "value" onto the Value property.
public interface Indicator<T>
{
DateTime Timestamp { get; }
T Value { get; }
}
public partial class TemperatureIndicator : Indicator<double>
{
public double Value { get { return this.Temperature; } }
}
Now have your repository implement methods that return objects of each type -- which can be used as (in .NET 4 or cast to in lower versions) objects of the interface type for common operations.

Should I expose a nullable or a HasFoo field? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm reading some data from an XML format and putting it in my classes and am just wondering what the best practice is regarding fields that can be empty and, if they are empty, have a default value. Values that haven't been supplied don't need to be written back to the file.
I was thinking of using nullable types, however, what's the best way in code of specifying a default value (though I wouldn't need a default value for every field as not all fields have a specified default value or the default value is 0)
At the moment I'm using this:
class SomeElement
{
public const int DefaultFoo = 123;
public int? Foo { get; set; }
}
but don't know if the following would be more obvious:
class SomeElement
{
// Setting HasFoo to false will set Foo to the default value
public bool HasFoo { get; set; }
// Setting Foo to anything will set HasFoo to true
public int Foo { get; set; }
}
As some of the classes have lots of properties, the second option will create lots more methods in the classes, however, might be easier to use if you don't care whether Foo has a value or not.
The final alternative might be using either a static method in the base class or an extension method to make the default easier to get (idea based on this)
// In some method using the class
int value = SomeElementBase.GetValueOrDefault(() => myObj.Foo);
// or an extension method
int value = myObj.GetValueOrDefault(x => x.Foo);
I'd still supply the DefaultFoo fields but the static/extension method might make it easier to access?
What are your thoughts? Has anybody come across this problem before? Should I just use default values and when saving back to the file omit fields that equal their default value?
I think a nullable field is preferable. No superfluous code keeping them in synch in your file, the intent is very clear, and you can just access Foo.HasValue which to my mind expresses your intent better than a separate HasValue property on the class.
I would use a combination of nullables for values that don't have a default value, and overriding the default getter for values that do have a default value (assuming that you don't actually need to know whether or not the value you're getting is the default or not):
class SomeElement {
public int? NoDefault {
get; set;
}
private int? m_hasDefault;
public int? HasDefault {
set { m_hasDefault = value; }
get {
if(m_hasDefault.HasValue)
return m_hasDefault;
else
return WhateverTheDefaultShouldBe;
}
}
}
Still returning nullables in both cases to keep things consistent, and to hide any differences between properties that have default values and those that don't to the calling code (this way you could easily change which values have defaults or not in the class without affecting the code that uses the class).

Categories

Resources