Using Generics to minimize repeated code C# [closed] - c#

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 have 3 classes Manager, TeamLead, Employee. These are generated from Database as I am using Entity framework. I can't do any changes here.
Class Manager()
{
string AddressLine1;
string AddressLine2;
string AddressLine3;
.
.
//Some other props
}
Class TeamLead()
{
string AddressLine1;
string AddressLine2;
string AddressLine3;
.
.
//Some other props
}
Class Employee()
{
string AddressLine1;
string AddressLine2;
string AddressLine3;
.
.
//Some other props
}
Now I another class in some other assembly,
Class AddressDetails
{
string AddressLine1;
string AddressLine2;
string AddressLine3;
}
And the current piece of code is,
Class WorkingPlace
{
Manager _manager;
TeamLead _teamLead;
Employee _employee;
// all the above obejects getting filled in various functions in this class
AddressDetails _addressDetails;
private SomeMethod1()
{
.
.
//doing some works
.
.
FillAddress("Manager");
}
private SomeMethod2()
{
.
.
//doing some works
.
.
FillAddress("TeamLead");
}
private FillAddress(string type)
{
if(type == "Manager")
{
_addressDetails.AddressLine1 = _manager.AddressLine1;
_addressDetails.AddressLine1 = _manager.AddressLine1;
_addressDetails.AddressLine1 = _manager.AddressLine1;
}
else if( type == "TeamLead")
{
_addressDetails.AddressLine1 = _teamLead.AddressLine1;
_addressDetails.AddressLine1 = _teamLead.AddressLine1;
_addressDetails.AddressLine1 = _teamLead.AddressLine1;
}
}
}
I want this to be,
FillAddress<T>(T typeObj)
{
_addressDetails.AddressLine1 = typeObj.AddressLine1;
_addressDetails.AddressLine1 = typeObj.AddressLine1;
_addressDetails.AddressLine1 = typeObj.AddressLine1;
}
//and Call it as,
FillAddress<Manager>(_manager);
Is it possible, I am new to Generics, I want to code effectively. Experts please help me. any other comments other than this let me know.

Not answering the question, but I see a need for the code to be refactored,
TO avoid repetitive code here,
Consider creating Address class an adding that as a reference in all the other classes
Class AddressDetails
{
string AddressLine1;
string AddressLine2;
string AddressLine3;
}
Then make your other classes like,
class Manager
{
AddressDetails address;
public Manager(AddressDetails address){
this.address=address;
}
}
class Employee
{
AddressDetails address;
public Manager(AddressDetails address){
this.address=address;
}
}
Even better, Use base class for all you Employees, as Manager and TeamLead all are employees and all have an address. Let others derive from it.
Now to answer your question, derive an interface from AddressDetails class and let your other classes implement it. Then create your generic method
FillAddress(IAddressable employee, Addresdetails newAddress)
{
employee.AddresssLine1=newAddress.AddressLine1;
..........
}

As i see your implementation, you may need to use some reflection. Assuming you have already instantiated _addressDetail, you could do something like this:
void FillAddress<T>(T value){
var typeInfo = typeOf(value);
_addressDetails.AddressLine1 = typeInfo.GetProperty("AddressLine1")?.GetValue(value) as string;
_addressDetails.AddressLine2 = typeInfo.GetProperty("AddressLine2")?.GetValue(value) as string;
_addressDetails.AddressLine3 = typeInfo.GetProperty("AddressLine3")?.GetValue(value) as string;
}

Here is a good MSDN article about generic methods. It should explain everything you need to know.
To answer your question:
Yes, that is possible.
The way you formatted your guess at a generic method is correct. Also, you can omit the <T> part, as described by the aforementioned article, as the compiler will infer the type from the arguments.

Related

Object Initialization directly while creating it (set value) [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 3 years ago.
Improve this question
I'm following this course here and this is live demo
Please I have few questions to ask you, as I want to confirm that I'm understanding what I'm reading :
1) Why does one set value directly while creating object in below code
Transaction t1 = new Transaction("8877", "6/25/2018");
instead of doing like the below; which doesn't work !!!
Transaction transac1 = new Transaction();
transac1.("1234", "2019/10/03");
2) Is public Transaction() { and public Transaction(string c, string d) overloading concept?
3) Is the below a constructor method, using overloading?
public Transaction()
{
tCode = " ";
tDate = " ";
}
4) Why Transaction class doesn't have properties, eventhough I only see two below fields/variable with private access modifiers. whereas I read in OOP book that you must always use properties not to expose fields from outside.
private string tCode;
private string tDate;
public interface ITransactions
{
// interface members
void showTransaction();
}
public class Transaction : ITransactions
{
private string tCode;
private string date;
public Transaction()
{
tCode = " ";
date = " ";
}
public Transaction(string c, string d)
{
tCode = c;
date = d;
}
public void showTransaction()
{
Console.WriteLine("Transaction ID: {0}", tCode);
Console.WriteLine("Date: {0}", date);
}
}
class Tester
{
static void Main(string[] args)
{
Transaction t1 = new Transaction("8877", "6/25/2018");
Transaction t2 = new Transaction("5656", "7/25/2018");
t1.showTransaction();
t2.showTransaction();
Console.ReadKey();
}
}
1)
[...] which doesn't work !!!
Transaction transac1 = new Transaction();
transac1.("1234", "2019/10/03");
Yes, this simply doesn't work, it is invalid syntax. Either you call the constructor new Transaction(); or new Transaction("8877", "6/25/2018");
2)
Is public Transaction() { and public Transaction(string c, string d) overloading concept?
Yes.
3)
Is the below a constructor method, using overloading?
[...]
There is no such thing as "constructor method". You have constructors and you have methods, but there aren't any "constructor methods".
4)
Why Transaction class doesn't have properties, even though I only see two below fields/variable with private access modifiers.
You don't need to expose all the private fields with public properties. It is not a requirement to have public properties for any private field you have. If you don't want to provide such access to any data in your class you don't need to. In this case you only need showTransaction().

Simple WCF Service [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 7 years ago.
Improve this question
I tried to write my First WCF service and here i have some problems,
First,I create a WCF Project,Then i added Entity Model.After that i added IEmpService.svc file.then i'm going to get a List of Customers.
I follow THIS BLOG POST
IEmpService
[ServiceContract]
public interface IEmpService
{
[OperationContract]
List<Customer> GetAllCustomers();
}
EmpService
public class EmpService : IEmpService
{
public EmpDBEntities dbent = new EmpDBEntities(); // I can't create thisone inside GetAllCustomer method.
public List<Customer> GetAllCustomers
{
//var x = from n in dbent.Customer select n; // This is what i need to get but in here this program not recognize `var` also.
//return x.ToList<Customer>();
}
}
Can anyope please tell me which point i'm missing ? or whythis problem happend? how to solve this ?
Not really sure what your question is, but did you define "Customer" as a DataContract? If that's the object that your service returns, you need to define it so the client can use it.
I am still confused by your question, but I will attempt an answer.
Your Customer class needs to have a DataContract with DataMembers if you want to return it.
You probably saw this example:
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
Also, do not return List. Microsoft has List defined, but this is a web service - the rest of the world (apple, android, linux, php, etc) will not know how to interpret a List.
Instead, change your function's signature to an array of strings.
[OperationContract]
string[] GetAllCustomers();
You should remove public keyword if you want to create this inside GetAllCustomer method. Like this:
public List<Customer> GetAllCustomers()
{
EmpDBEntities dbent = new EmpDBEntities();
var x = from n in dbent.Students select n;
return x.ToList<Student>();
}

Framework for handling serialization in "key:value;key:value;key:value;key:value;" format [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
Of course it's easy to write the code to deserialize from this format. I've already done it, but I don't like.
The single responsibility principle states that I should have a generic class that worries only about this kind of serialization. And the task is generic enough to be coped by a framework.
If you converted it to a JSON string like (which should be easy)
var jsonArray = “[{'key':'value'}, {'key':'value'}, {'key':'value'}, {'key':'value'}]”;
then you could easily deserialize it with Json.NET into whatever you want and Json.NET takes care of converting the values to the right types for you:
MyType1[] result = JsonConvert.Deserialize<MyType1[]>(jsonArray);
MyType2[] result = JsonConvert.Deserialize<MyType2[]>(jsonArray);
public class MyType1
{
public string key { get; set; }
public string value { get; set; }
}
public class MyType2
{
public string key { get; set; }
public double value { get; set; }
}
or even just as a dictionary (I hope I have the syntax correct, I didn't test it):
var jsonDic = “{{'key':'value'}, {'key':'value'}, {'key':'value'}, {'key':'value'}}”;
var result = JsonConvert.Deserialize<Dictionary<string, string>>(jsonDic);
The single responsibility class (just as an example):
public class KeyValueParser
{
public static TResult ParseKeyValueString<TResult>(string keyValueString)
{
keyValueString = ConvertToJson(keyValueString);
TResul result = JsonConvert.DeserializeObject<TResult>(keyValueString);
return result;
}
private static string ConvertToJson(string keyValueString)
{
// convert keyValueString to json
}
}
usage
var jsonDic = “{{'key':'value'}, {'key':'value'}, {'key':'value'}, {'key':'value'}}”;
var result = KeyValueParser.ParseKeyValueString<Dictionary<string, string>>(jsonDic);
I don't really understand the question.
If it is something your program does a lot then move the function to some area that it is easy to get too (or a nuget package if a lot of your systems need it). If it happens in one place in your code put it quite close to that place.

array of pointers to objects in another class [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 8 years ago.
Improve this question
I have to create class like DataBase that will contain menu, adding users, editing them, deleting etc.
Users are from class User.
It looks like:
class base
{
protected int mAccounts=0;
protected const int mMaxAccs=10;
osoba[] list = new osoba[mMaxAccs];
public void menu(){...}
public void add()
{
user user1("Jurand","ze Spychowa",15231512,"1410-10-26","hue#x.com");
mAccounts++;
}
... useless code there
}
then there is User class
class user
{
private string mName;
private string mSurname;
private int mPesel;
private DateTime mBDate;
private string mEmail;
osoba(string mName2, string mSurname2, string mPesel2, string mBDate2, string mEmail2)
{
mName = mName2;
mSurname = mSurname2;
mPesel = Convert.ToInt32(mPesel2);
mBDate = Convert.ToDateTime(mBDate2);
mEmail = mEmail2;
}
The problem is adding new accounts. I totally don't know how to make it working
So the users will be stored in base class and you will have access to edit and add them etc.
Anyone know how to make it working (Creating objects properly)?
I suggest adding properties to User class:
class User
{
public string mName { get; private set; }
public string mSurname { get; private set; }
public int mPesel { get; private set; }
public DateTime mBDate { get; private set; }
public string mEmail { get; private set; }
//constructor for User class
public User(string mName2, string mSurname2, string mPesel2, string mBDate2, string mEmail2)
{
mName = mName2;
mSurname = mSurname2;
mPesel = Convert.ToInt32(mPesel2);
mBDate = Convert.ToDateTime(mBDate2);
mEmail = mEmail2;
}
}
and modify your add method (also changed object where you store data from array to List):
class MyDB
{
List<User> list = new List<User>();
public void add()
{
//use constructor to create new object
User person = new User("Jurand", "ze Spychowa","15231512","1410-10-26","hue#dupa.com");
//add object to list
list.Add(person);
}
}
Its not good idea to mix different languages in code so try avoiding naming objects/methods like "osoba".
You will probably benefit from reading following articles (in Polish):
C# Constructors
C# Properties
I belive that only thing that is missing in your add() method is:
osoba[mAccounts] = user1;
before mAccounts++ line.
Make fields public only if your User class is going to be stupid data object which only store data and contain no methods (maybe except formatting, converting etc.).

How to pass anonymous type to method as a parameter? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What’s the return type of an anonymous class
I'm creating an anonymous type with query like the following:
Caller code:
var query= from p in _db.ExecuteDataSet(SQL).Tables[0].AsEnumerable()
select new {
ProductCode = p.Field<string>("PRODUCT_CODE"),
ProductName = p.Field<string>("PRODUCT_NAME")
};
foreach(var product in query)
{
WriteProduct(product);
}
Method is like:
void WriteProduct(object prod)
{
// access the product
}
I fail to get the correct Parameter Type for the WriteProduct method. Please help me.
Yes you can.
public class Program
{
private static void Thing(dynamic other)
{
Console.WriteLine(other.TheThing);
}
private static void Main()
{
var things = new { TheThing = "Worked!" };
Thing(things);
}
}
But as a small, minor detail, DON'T!
Anonymous types are anonymous for a reason, they aren't first class entities in your code, they're more of a convenience. If a type is that important, define it as such.
There are 3 ways to talk to an anonymous type:
reflection (obtain the properties via obj.GetType().GetProperties() / prop.GetValue(obj, null), etc)
dynamic (i.e. obj.ProductCode and obj.ProductType, for dynamic obj) - an optimized and prettier version of the above
cast-by-example : DO NOT USE
Your WriteProduct must use one of those; or alternatively : use something other than an anonymous type; a Tuple<...>, maybe (although that tends to make it hard to know what the data is) - or an appropriately defined custom interface, class or struct.
Correct me if I'm wrong, but I think you should create a temporary class to store the product.
select new TempProduct {
productCode = p.Field<string>("PRODUCT_CODE"),
productName = p.Field<string>("PRODUCT_NAME")
};
With e.g a class like this
public class TempProduct
{
public String productCode { get; set; }
public String productName { get; set; }
}
This isn't exactly what you are asking for, but your select has only two properties, so how about passing these two to the method?
foreach(var product in query)
{
WriteProduct(product.ProductCode, product.ProductName);
}
// ...
void WriteProduct(string productCode, string productName)
{
// ...
}

Categories