This question already has answers here:
C# vs Java Enum (for those new to C#)
(13 answers)
Is it possible to add custom properties to c# enum object?
(2 answers)
Closed 2 years ago.
I have a very basic question. In Java, it is possible to point attributes and variables to Enums, such as:
public enum DayTime{
Morning("Morning"),
Afternoon("Afternoon"),
Night("Night");
private string description;
Daytime(string description){
this.description = description;
}
public string getDescription(){
return description;
}
}
Is it possible to apply the same concept to C#? I am trying to get modular descriptions to products, whereas their name, contents and characteristics would be shown in a string of text, and Enums looked like the best alternative to modify this text according to which characteristic is selected.
C# enums are very basic compared to Java enums. If you want to simulate the same kind of behavior you need to use a class with an inner enum:
using System.Collections.Generic;
public sealed class DayTime
{
public static readonly DayTime Morning = new DayTime("Morning", InnerEnum.Morning);
public static readonly DayTime Afternoon = new DayTime("Afternoon", InnerEnum.Afternoon);
public static readonly DayTime Night = new DayTime("Night", InnerEnum.Night);
private static readonly List<DayTime> valueList = new List<DayTime>();
static DayTime()
{
valueList.Add(Morning);
valueList.Add(Afternoon);
valueList.Add(Night);
}
//the inner enum needs to be public for use in 'switch' blocks:
public enum InnerEnum
{
Morning,
Afternoon,
Night
}
public readonly InnerEnum innerEnumValue;
private readonly string nameValue;
private readonly int ordinalValue;
private static int nextOrdinal = 0;
private string description;
internal DayTime(string name, InnerEnum innerEnum)
{
this.description = name;
nameValue = name;
ordinalValue = nextOrdinal++;
innerEnumValue = innerEnum;
}
public string Description
{
get
{
return description;
}
}
//the following methods reproduce Java built-in enum functionality:
public static DayTime[] values()
{
return valueList.ToArray();
}
public int ordinal()
{
return ordinalValue;
}
public override string ToString()
{
return nameValue;
}
public static DayTime valueOf(string name)
{
foreach (DayTime enumInstance in DayTime.valueList)
{
if (enumInstance.nameValue == name)
{
return enumInstance;
}
}
throw new System.ArgumentException(name);
}
}
Given this complexity, it may be best to rewrite your logic in a way that's more natural for C# without using enums.
Related
This question already has answers here:
Invoking all setters within a class using reflection
(4 answers)
Closed 5 years ago.
I have a POJO object and a collection of appropriate data.
import java.util.ArrayList;
import java.util.List;
public class TestPojo {
private String name;
private String number;
private String id;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public static void main(String[] args) {
TestPojo test = new TestPojo();
List<String> sampleData = new ArrayList<>();
sampleData.add("Bob");
sampleData.add("641-613-623");
sampleData.add("id-1451");
sampleData.add("Male");
test.setName(sampleData.get(0));
test.setNumber(sampleData.get(1));
test.setId(sampleData.get(2));
test.setSex(sampleData.get(3));
}
}
My question is how can i fill my POJO object with data in a loop? Is it posible to iterate all object setters and set data from List in appropriate places? I know that reflection can help in this case.
Here is an simple example to call setters via reflection (which needs to be adjusted):
[if this is a good approach, is another question. But to answer your question:]
public static void main(String[] args) throws Exception
{
//this is only to demonstrate java reflection:
Method[] publicMethods = TestPojo.class.getMethods(); //get all public methods
TestPojo testObj = TestPojo.class.newInstance(); //when you have a default ctor (otherwise get constructors here)
for (Method aMethod : publicMethods) //iterate over methods
{
//check name and parameter-count (mabye needs some more checks...paramter types can also be checked...)
if (aMethod.getName().startsWith("set") && aMethod.getParameterCount() == 1)
{
Object[] parms = new Object[]{"test"}; //only one parm (can be multiple params)
aMethod.invoke(testObj, parms); //call setter-method here
}
}
}
You can also save all setter-methods in an list/set for later re-use...
But as others already said, you have to be careful by doing so (using reflection)!
Cheers!
You can't easily - and you shouldn't.
You see, your POJO class offers some setters. All of them have a distinct meaning. Your first mistake is that all of these fields are strings in your model:
gender is not a string. It would rather be an enum.
"number" is not a string. It should rather be int/long/double (whatever the idea behind that property is)
In other words: you premise that "input" data is represented as array/list is already flawed.
The code you have written provides almost no helpful abstractions. So - instead of worrying how to call these setter methods in some loop context - you should rather step back and improve your model.
And hint: if this is really about populating POJO objects from string input - then get your string into JSON format, and use tools such as gson or jackson to do that (reflection based) mapping for you.
"Iterating over methods" seems pretty much of a wrong idea in OO programming. You could simply add a constructor to your class setting all of your attributes, and then just call that constructor in a loop as desired to create new objects with data you desire.
In your class define:
public TestPojo(String name, String number, String id, String sex){
this.name = name;
this.number = number;
this.id = id;
this.sex = sex;
}
Also using a List makes no much sense here. I'd recommend using a HashMap to then iterate over it in a for loop making proper calls of the above constructor.
This question already has answers here:
Accessing objects of other classes
(3 answers)
Closed 6 years ago.
I dont know how to create and use an object from an other class in an other class. for example, i want the Publisher to be created from another class (Item)
public class Item {
private String title;
private String publisher;
private int price,year,quantity;
Item(String title,String publisher,int price,int year,int quantity){
//Constructor goes here
}
}
//this is the publisher class:
public class Publisher {
private String name,address,country,city;
Publisher(String name,String address,String country,String city){
this.setName(name);
this.setAddress(address);
this.setCountry(country);
this.setCity(city);
}
}
What did you try? It's very simple:
public class Item {
....
void Test() {
Publsiher p = new Publisher("a","b","c","d");
//do some things
}
}
public class Item{
public Item(){
Publisher p = new Publisher('Name','Address','Country','City');
}
}
Inside the constructor Item() create a new Publisher object "p" with input values of your choice ('name','address, 'country', 'city').
This question already has answers here:
Using Spring IoC to set up enum values
(13 answers)
Closed 7 years ago.
I have the following enum:
public class Wrapper(){
public enum MyEnum{
A("a_id", "a_source", "a_target"),
B("b_id", "b_source", "b_target"),
...
Z("z_id", "z_source", "z_target"),
String id;
String source;
String target;
myEnum(String i, String s, String t){
id = i;
source = s;
target = t;
}
}
}
If possible I would like to be able to specify the enum parameters (e.g. "a_id") in application.properties so that I can modify them and inject them in as needed. I was initially thinking of something like:
public class Wrapper(){
#Value("${a.id}")
private String A_ID;
#Value("${a.source}")
private String A_SOURCE;
#Value("${a.target}")
private String A_TARGET;
public enum MyEnum{
A(A_ID, A_SOURCE, A_TARGET),
...
}
}
with application.properties looking like:
a.id=a_id
a.source=a_source
a.target=a_target
The problem is that I cannot call A_ID inside the enum without making it static but if I make it static I cannot perform dependency injection (from my understanding).
What would be the best approach to having those strings externally configurable and injected in ?
Possibly this guy has the answer: https://stackoverflow.com/a/711022/4546150
As dnault said, trying to get configuration values from application.properties wont be possible with Spring - you would need to guarantee that Spring has loaded and parsed the configuration, then try to inject it into a static object.
But, as the SO post I linked mentions - do you need to use Springs configuration loading for this? I believe Resource Bundle was mentioned as an alternative:
public enum MyEnum {
A;
public final String id;
public final String source;
public final String target;
MyEnum() {
this.id = BUNDLE.getString("A.id");
this.source = BUNDLE.getString("A.source");
this.target = BUNDLE.getString("A.target");
}
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(...);
}
You can't do it. But you can have:
public enum MyEnum {
A, B, C, .... Z;
String idKey() { return name().toLowerCase() + ".id"; }
String sourceKey() { return name().toLowerCase() + ".source"; }
String targetKey() { return name().toLowerCase() + ".target"; }
};
Then you can have property file as you've define and then somewhere in the client code:
MyEnum e = ...
properties.getProperty(e.idKey());
This question already has answers here:
Struct like objects in Java
(20 answers)
Closed 9 years ago.
In C I would create a data structure as below:
struct file_data_format
{
char name[8][20];
float amp[8];
int filter[8];
};
extern struct file_data_format f_data;
Then I could read or write this whole structure to a file or memory location.
How would I do this in a class in java?
You should read basics of Java before asking. Structure in C can be written as Class in Java.
public class FileDataFormat implements Serializable {
String[][] name = new String[8][20];
float[] amp = new float[8];
int[] filter = new int[8];
public FileDataFormat() {
}
public void setName(String[][] name) {
this.name = name;
}
public String[][] getName() {
return this.name;
}
// next getters and setters
}
I pretty recommend OOP(encapsulation, polymorphism, inheritance).
If you want to achieve a similar effect, you can do the following.
Unfortunately, you don't have so much control over how it's represented in memory as you do in c
public class file_data_format
{
public char name[8][20];
public float amp[8];
public int filter[8];
}
...
public static void main()
{
file_data_format fdf = new file_data_format();
fdf.name = charArrayIGotFromSomewhere
}
public class FileDataFormat {
private String name;
private float amp;
private int filter;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getAmp() {
return amp;
}
public void setAmp(float amp) {
this.amp = amp;
}
public int getFilter() {
return filter;
}
public void setFilter(int filter) {
this.filter = filter;
}
}
The equivalent of a struct in Java is a JavaBean, as other answers has shown you.
From Wikipedia, a JavaBean :
is serializable
has a 0-argument constructor
allows access to properties using getter and setter methods.
To write and read it from file or memory, it is not as simple as in C. You would typically use Java Object serialization to write/read your objects to an ObjectInputStream/ObjectOutputStream, that could be attached to a file or a byte array.
This question already has answers here:
How to retrieve Enum name using the id?
(11 answers)
Closed 9 years ago.
I need to do look up in an enum by an int . The enum is as folows :
public enum ErrorCode{
MissingReturn(1,"Some long String here"),
InvalidArgument(2,"Another long String here");
private final int shortCode ;
private final String detailMessage;
ErrorCode(shortCode ,detailMessage){
this.shortCode = shortCode ;
this.detailMessage= detailMessage;
}
public String getDetailedMessage(){
return this.detailMessage;
}
public int getShortCode(){
return this.shortCode ;
}
}
Now Is need to have a lookup method that would take an int code and should return me the String message pertaining to that code that is stored in the Enum.Passing a "1" should return me the String "Some long String here". What is the best way to implement this functionality?
public static String lookUpMessageFromCode(int code){
}
P.S: Is the class EnumMap useful for this kind of use case? If yes,please let me know why?
Depending on the int values that you associated with your enum, I would add a static array of ErrorCodes, or a static Map<Integer,ErrorCode> to your enum class, and use it to do a lookup in the message from code method. In your case, an array is more appropriate, because you have values 1 and 2 which are small. I would also change the signature to return ErrorCode.
private static final ErrorCode[] allErrorCodes = new ErrorCode[] {
null, MissingReturn, InvalidArgument
};
public static ErrorCode lookUpByCode(int code) {
// Add range checking to see if the code is valid
return allErrorCodes[code];
}
The callers who need the message would obtain it like this:
String message = ErrorCode.lookUpByCode(myErrorCode).getDetailedMessage();
I would simply iterate through your Enum values and check the code. This solution lets you utilize the existing Enum with out creating another object to manage.
public enum ErrorCode {
MissingReturn(1, "Some long String here"),
InvalidArgument(2, "Another long String here");
private final int shortCode;
private final String detailMessage;
ErrorCode(int shortCode, String detailMessage) {
this.shortCode = shortCode;
this.detailMessage = detailMessage;
}
public String getDetailedMessage() {
return this.detailMessage;
}
public int getShortCode() {
return this.shortCode;
}
public static String lookUpMessageFromCode(int code) {
String message = null;
for (ErrorCode errorCode : ErrorCode.values()) {
if (errorCode.getShortCode() == code) {
message = errorCode.getDetailedMessage();
break;
}
}
return message;
}
public static void main(String[] args) {
System.out.println(ErrorCode.lookUpMessageFromCode(1));
System.out.println(ErrorCode.lookUpMessageFromCode(2));
}
}
One thing to note
The Enum constructor is missing the type information regarding its parameters.
ErrorCode(int shortCode, String detailMessage) {
this.shortCode = shortCode;
this.detailMessage = detailMessage;
}
Here is another option:
public static String lookUpMessageFromCode(int code){
for(ErrorCode ec:ErrorCode.values()){
if(ec.shortCode==code)
return ec.detailMessage;
}
return null;
}