Let's say that I have many resource files: a.resx, b.resx and c.resx
and I use it like this:
groupSettingsLogin.Caption = Resources.a.login_caption;
or
groupSettingsLogin.Caption = Resources.b.login_caption;
If I have a global variable public String ResourceName and I set this at start at a certain value:
MyGlobalVariables.ResourceName = "a";
then can I somehow refer to the resource dynamically as:
groupSettingsLogin.Caption = Resources."MyGlobalVariables.ResourceName".login_caption;
I know the above line is not correct but is there a way to to something like this?
Or if not is there an alternative way for it?
You can use this
var resourceManager = new ResourceManager("YourNamespace." + MyGlobalVariables.ResourceName, Type.GetType("YourNamespace." + MyGlobalVariables.ResourceName).Assembly);
var login_caption = resourceManager.GetString("login_caption", CultureInfo.CurrentCulture);
I've checked this works fine. Previous answer was incorrect
Try this:
// MyGlobalVariables.Resources is `dynamic`
MyGlobalVariables.Resources = Resources.a;
groupSettingsLogin.Caption = MyGlobalVariables.Resources.login_caption;
Look into the generated code. There you can see how it itself accesses the underlying data. Should be very easy. Single method call. There's no magic underneath the generated properties. They are a thin facade. I once looked but I don't remember what's there.
Related
is it possible to evaluate a single string in c#. The string itself will only be determined during run-time and therefore cannot be set before hand. please see example:
var a = "a == b";
if(a){
//do something
}
EDITED:
This is a actual example of what i would like computed:
var evaluationToBeDone = "MUST_CE_I = \"MUST_CE_I\"";
if(evaluationToBeDone){
// i will do something if the above is true
}
I see what you're trying to do, but the approach doesn't make sense. When you make a variable into an object, the program only reads it as letters, not any logic inside of the object. Try doing this:
var a = "MUST_CE_I"
var b = "\"MUST_CE_I\""
if (a == b)
{
do stuff
}
I assume you want your second string to have the " " quotes, so this should give you what you need. Even though the if statement will always return false since the two variables are not equal.
I want to parse some data into enum but I'm stumbling upon a problem. Namely, when I try this code:
Languages lang = Enum.Parse(typeof(Languages), languageChooser.SelectedItem, true);
I get info that it has some invalid arguments. I think there is a problem with the first one but in every tutorial I've found the first arg looks like this.
Any help or advice?
The issue is your second parameter, not the first. languageChooser.SelectedItem more than likely returns an instance of object rather than string. I'm not sure what type you're using to back your languageChooser, so it's hard to say what the proper fix is. It could be any of the following:
// languageChooser is bound to an IEnumerable<string>
var lang =
Enum.Parse(typeof(Languages), languageChooser.SelectedItem as string, true);
// languageChooser is bound to something with a proper ToString() implementation
var lang =
Enum.Parse(typeof(Languages), languageChooser.SelectedItem.ToString(), true);
// languageChooser is an IEnumerable<SomeOtherType> where SomeOtherType has a property
// that indicates the language
var obj = languageChooser.SelectedItem as SomeOtherType;
var lang = Enum.Parse(typeof(Languages), obj.SomeLanguageProperty, true);
I am trying to insert a string at a position for C# string, its failing
here is the snippet.
if(strCellContent.Contains("<"))
{
int pos = strCellContent.IndexOf("<");
strCellContent.Insert(pos,"<");
}
please tell me the solution
The return value contains the new string that you desire.
strCellContent = strCellContent.Insert(pos,"<");
Gunner and Rhapsody have given correct changes, but it's worth knowing why your original attempt failed. The String type is immutable - once you've got a string, you can't change its contents. All the methods which look like they're changing it actually just return a new value. So for example, if you have:
string x = "foo";
string y = x.Replace("o", "e");
the string x refers to will still contain the characters "foo"... but the string y refers to will contain the characters "fee".
This affects all uses of strings, not just the particular situation you're looking at now (which would definitely be better handled using Replace, or even better still a library call which knows how to do all the escaping you need).
I think you might be better of with a Replace instead of an Insert:
strCellContent = strCellContent.Replace("<", "<");
Maybe doing Server.HtmlEncode() is even better:
strCellContent = Server.HtmlEncode(strCellContent);
When I look at your code I think you want to do a replace, but try this:
if(strCellContent.Contains("<"))
{
int pos = strCellContent.IndexOf("<");
strCellContent = strCellContent.Insert(pos,"<");
}
.Contains is not a good idea here, because you need to know the position. This solution will be more efficient.
int pos = strCellContent.IndexOf("<");
if (pos >= 0) //that means the string Contains("<")
{
strCellContent = strCellContent.Insert(pos,"<"); //string is immutable
}
As others have explained with the code, I will add that
The value of the String object is the
content of the sequential collection,
and that value is immutable (that is,
it is read-only).
For more information about the immutability of strings, see the Immutability and the StringBuilder Class section.
from: http://msdn.microsoft.com/en-us/library/system.string.aspx
I'm trying to consume a DLL-located method in C#, which returns a dynamic array of structs. What ever I do, I receive the well-know "Object reference not set to an instance of an object" error, Here is my last code and it still tells that error:
string v_user = "kish";
string v_pass = "u";
string v_number = "p";
string v_address = "url has been replaced with this string";
string v_cid = "abc";
Cls_SMS.SMSReceive.STC_SMSReceive[] xts;
Cls_SMS.SMSReceive px = new Cls_SMS.SMSReceive();
// *** is the below line
xts = px.ExtendReceiveSMS(v_user, v_pass, v_number, v_address, v_cid);
int upper_bound = xts.GetUpperBound(0);
for (int counter = 0; counter < upper_bound; counter++)
{
Response.Write(xts[counter].Message.ToString());
Response.Write("<br>");
}
please note that my main problem is about receiving a dynamic array of structs with struct type name (Cls_SMS.SMSReceive.STC_SMSReceive) and other aspects such as connecting to the remote server is not my problem. I just want to allocate a dynamic array of vendor-defined structs to the left side of the assignment opeator in * line.
Please help me.
Thank you very much.
It is not clear how the px.ExtendReceiveSMS(v_user, v_pass, v_number, v_address, v_cid); method assigns the array, it probably doesn't assign it at all because of the exception. Here's how you could assign a dynamic array and return it:
public STC_SMSReceive[] ExtendReceiveSMS()
{
STC_SMSReceive[] result = new STC_SMSReceive[2];
result[0] = new STC_SMSReceive();
result[1] = new STC_SMSReceive();
return result;
}
Also if it is dynamic you might also take a look at List<T>:
public IList<STC_SMSReceive> ExtendReceiveSMS()
{
IList<STC_SMSReceive> result = new List<STC_SMSReceive>();
list.Add(new STC_SMSReceive());
list.Add(new STC_SMSReceive());
return result;
}
This has nothing to do with the strict array; simply, the library method you are using is returning null.
There are various possibilities here:
maybe returning null is an expected return value for some scenarios; check the documentation
maybe you need some additional configuration, or maybe you need to call some additional method (GetTheData() would be too hopeful ;p), or wait for some other event before this data is available - check the documentation
maybe it is simply a library bug; contact the vendor
If all 3 routes fail, personally I'd just open it reflector and look for a scenario that might return null. Then tell the vendor to fix the bug or clarify the documentation as appropriate.
If you replace your separate declaration of xts with:
var xts = px.ExtendReceiveSMS(v_user, v_pass, v_number, v_address, v_cid);
what type does Visual Studio now report xts to be?
You can tell by hovering over xts with your cursor and reading it off the tooltip.
Other than that if the vendor is reporting that it works for other users, you must have one (or more) of the arguments wrong. Ask the vendor for some example code that works so you can check to see if that connects to the server properly. If it does then the error is in the other arguments, if not then it's a problem with your connection to the server.
I've found what seems to be the C# equivalent of a FOR-CASE structure in a project I'm working on:
foreach (string param in params.Split(';'))
{
string[] parts = param.Split('=');
string key = parts[0].Trim().ToLower();
string value = parts[1].Trim();
switch (key)
{
case "param1": this.param1 = value; break;
case "param2": this.param2 = value; break;
case "param3": this.param3 = value; break;
case "param4": this.param4 = value; break;
default: break;
}
}
(Variable names changed to protect the guilty.)
How would you implement this code?
I don't think the code in your question is anything like the code you linked to....
The code in the question looks like something I might do if I wrote a command line tool.
Am I stupid for not seeing whats wrong with the code in the question?
An alternative is to use reflection to fill parameter value variables. I've done it that ways sometimes too.
BTW: I once wrote a program in a script language that had switch as the only flow control mechanism and no gosub/return. The code in my program was structured a bit like the one you linked to. A massive switch on a sort of instruction pointer variable that got reassigned at the end of every case and an almost infinite loop around the switch. It got the job done.
I see you that you already have multiple fields in your class that you use to hold the variables. In that case, what you are doing is fine.
Otherwise, you can have 1 HashTable (maybe add in the C# indexor as a twist) to hold all of them, and your loop will end up like this:
foreach (string param in params.Split(';'))
{
string[] parts = param.Split('=');
string key = parts[0].Trim().ToLower();
string value = parts[1].Trim();
MyHashTable[key] = value;
}
The problem with this approach is that you should only have 1 type of value. For example, if your param list can contain both string and int types, it makes the code messier, especially you need to perform error checking and validation and stuff.
I personally would stick with what you already have.
You could use reflection for this:
Type t = this.GetType();
foreach (string param in params.Split(';'))
{
string[] parts = param.Split('=');
string key = parts[0].Trim().ToLower();
string value = parts[1].Trim();
t.GetProperty(key).SetValue(this, value, null);
}
For what it's worth, the WTF article was a WTF because its outer loop was completely useless, as noted in the article - it was just as easy, and more direct, just to set an index variable directly than to loop and test it.
Not sure if I understand either but it sounds like you're complicating yourself. Don't reinvent the wheel, use BCL classes as much as you can, these classes are proven to work efficiently and save you lots of time. Sounds like you could implement it with some sort of Dictionary<,> along with, like Guge suggested, Reflection.
I actually think the OP's code is fine. It's not perfect -- there might be simpler or cleaner ways to do it, but it effectively allows for readable mappings between member/property names and input-parameter names. It leaves your properties strongly typed (unlike the hashmap/dictionary solutions, unless your class has only one type for all its properties...) and gives you one fairly-obvious place to fix or add mappings.
Or Regex:
string parms = "param1=1;param2=2;param3=3";
string[] parmArr = parms.Split(';');
string parm1 = Regex.Replace(parmArr[0], "param1=", "");
string parm2 = Regex.Replace(parmArr[1], "param2=", "");
string parm3 = Regex.Replace(parmArr[2], "param3=", "");