I'm trying to convert an object array of my class to a string array.
In this example I have two classes. In one of my classes I want to creat two variables, objects of the other class. On variable will be a array and the other a "regular" variable.
Two classes name. ShowResult and Game.
In the Game class I write:
private ShowResult[] _showResults;
private ShowResult _showResult;
In my properties in my Game class I try to convert this two variables to string array and string:
public string[] ShowResults
{
get { return _showResults.ToString().ToArray(); }
set { _showResults.ToString().ToArray() = value; }
}
public string ShowResult
{
get { return _showResult.ToString(); }
set { _showResult = value; }
}
This doesn't work. I really want my custom object to be converted to string array and to string. But I get an error.. I know I can, but I don't know just how..
If anyone has any suggestion I would be greatful. OBS, this is just an example. But still I don't get why it wont work..?
By the way, sorry for my bad english. ;)
Best regards
Try this:
_showResults.Select(a => a.ToString()).ToArray()
Given the nature of your code (i.e. strings appear to map directly to ShowResults instances), you might want to consider implementing implicit operators:
ShowResults s = "hello";
string ss = s;
Console.WriteLine(ss); // "hello"
class ShowResults
{
public string SomeProp
{
get; private set;
}
public static implicit operator ShowResults(string s)
{
//this is where you'd parse your string
//to form a valid ShowResults
return new ShowResults{SomeProp = s};
}
public static implicit operator string(ShowResults s)
{
return s.SomeProp;
}
}
Related
I want to be able to do something like
public string[]|string stringsOrSingleString;
I want to create a variable that can be an array or a non-array of a specific type (a string in the example).
Example usage
I want to be able to do stringsOrSingleString = "bla" or stringsOrSingleString = new string[] { "bla" };
Do I need a custom class to do this? Preferably, I don't want to use a custom class, but if necessary then ok.
I should be able to tell later on if the value assigned was an array or non-array, using typeof or is, or something.
The whole reason for this ordeal is that I have a javascript API(that I didn't create), and I am trying to make a C# api that follows the JS api/syntax as close as possible.
Is this possible?
May be you want something like this?
public class Item<T>
{
public T Value => this.Values.Length > 0 ? this.Values[0] : default(T);
public T[] Values { get; set; }
}
The class has an array of values and a single value. There are some implementations like this, for example, when you select files with OpenFileDialog: you have a list of files (for MultiSelect case) and also a single SelectedFile. My answer is focused with this in mind. If you need another thing, give more information.
UPDATE
You can update previous class in this way:
public class Item<T>
{
public T Value => this.Values.Length > 0 ? this.Values[0] : default(T);
public T[] Values { get; set; }
public T this[int index] => this.Values[index];
public static implicit operator Item<T>(T value)
{
return new Item<T> { Values = new[] { value } };
}
public static implicit operator Item<T>(List<T> values)
{
return new Item<T> { Values = values.ToArray() };
}
public static implicit operator Item<T>(T[] values)
{
return new Item<T> { Values = values };
}
}
Example usage:
Item<string> item = "Item1";
string text = item.Value;
string sameText = item[0];
Item<string> items = new[] { "Item1", "Item2" };
string[] texts = item.Values;
string item1 = item[0];
string item2 = item[1];
You can create an instance using a simple object or an array. You can access to the first value using Value property and to all items using Values. Or use the indexer property to access to any item.
In C# you need to know the type of the variable. It's difficult work in the same form of JavaScript. They are very different languages.
I would like to return an object, which stores the return values from other class methods as properties on the return object. The problem is that I do not know which is the best way to do this in C#. Currently I am using a sort of JavaScript-ish approach. Because I do not know the return type, I use the dynamic keyword.
class Test {
public static dynamic MyExportingMethod() {
return new {
myString = MyStringMethod(),
myInt = MyIntMethod()
};
}
public static string MyStringMethod() {
return "Hello";
}
public static int MyIntMethod() {
return 55;
}
}
And then being able to access them like so,
var myReturnObjWithProps = Test.MyExportingMethod();
myReturnObjWithProps.myString; // should be "Hello"
So my questions are, should I use the dynamic return type? Am I not just returning an anonymous object?
should I use the dynamic return type?
Yes - a method that returns dynamic effectively returns an object, so you have to use dynamic in order to access it's properties at runtime without reflection.
Am I not just returning an anonymous object?
You are, but the declared type of the method is effectively object so its properties cannot be referenced at compile-time.
Bottom line - you should avoid returning anonymous types from methods if at all possible. Use a defined type, or keep the creation and usage of the anonymous type in one method so you can use var and let the compiler infer the type.
Make a class for the return type. You want something strongly typed, both for performance and for clarity.
class Foo
{
string MyString { get; set}
int MyInt { get; set}
}
class Test
{
public static Foo MyExportingMethod()
{
return new Foo
{
MyString = MyStringMethod(),
MyInt = MyIntMethod()
};
}
public static string MyStringMethod()
{
return "Hello";
}
public static int MyIntMethod()
{
return 55;
}
}
You should use dynamic sparingly. This way anyone can see what your method is returning. If you return dynamic the caller has no way of knowing what to look for in the dynamic without looking at the source for your method. That way the abstraction goes away and well-structured programming is all about abstraction.
An alternative to creating a new class simply for a method return would be ValueTuple:
public static (string myString, int myInt) MyExportingMethod()
{
return (MyStringMethod(), MyIntMethod());
}
var (myString, myInt) = Test.MyExportingMethod();
myString; // == "Hello"
I need to setup a Property with two arguments, for example, to append text in a log file.
Example:
public string LogText(string text, bool Overwrite)
{
get
{
return ProgramLogText;
}
set
{
ProgramLogText = value;
}
}
How do I do this?
(in the example above, I need to pass the text I want to be written in the file and 1 to overwrite (0 as default value for appending the text), else append to a text file, but when I get, I just need the text.)
You can extract class - implement your own class (struct) with Text and Overwrite properties and add some syntax sugar:
public struct MyLogText {
public MyLogText(string text, bool overwrite) {
//TODO: you may want to validate the text
Text = text;
Overwrite = overwrite;
}
public string Text {get;}
public bool Overwrite {get;}
// Let's add some syntax sugar: tuples
public MyLogText((string, bool) tuple)
: this(tuple.Item1, tuple.Item2) { }
public void Deconstruct(out string text, out bool overwrite) {
text = Text;
overwrite = Overwrite;
}
public static implicit operator MyLogText((string, bool) tuple) => new MyLogText(tuple);
//TODO: You may want to add ToString(), Equals, GetHashcode etc. methods
}
And now you can put an easy syntax
public class MyClass {
...
public MyLogText LogText {
get;
set;
}
...
}
And easy assignment (as if we have a property with 2 values):
MyClass demo = new MyClass();
// Set two values in one go
demo.LogText = ("some text", true);
// Get two values in one go
(string text, bool overWrite) = demo.LogText;
You can't.
However, you have a few possible alternative approaches: create a method, or use a Tuple instead or create a class/struct and pass as a parameter (which has been answered by someone else).
Below are some alternative methods that can also be used instead.
Alternative Method 1
Create a Tuple, but then you'd have to return a tuple string, bool.
public Tuple<string, bool> LogText { get; set; }
I wouldn't do this method because then your getter would also return two values.
Alternative Method 2
Create getter and setter methods instead.
public string GetLogText() => ProgramLogText;
public void SetLogText(string text, bool overwrite) => ProgramLogText = text; // and implement in this method your use of overwrite.
is it possible to have a public method that returns multiple values and then later call that method only retrieving the value that you want?
public static string Values()
{
string length = DAL.Util.getlength();
string Name = DAL.Util.getName(ddlID.SelectedValue);
return length + Name;
}
now I know if I were to call this method just by saying
string a = Values();
it would return the concatenated string of both length and Name, but is there anyway to call just a specific variable from that method even if it were 10 variables long?
Thanks for any advice and help you can provide.
It sounds like you should actually be returning a reference to an object which contains the various different bits of state, instead of returning a single string. Then the caller can decide which bits of state they're really interested in, and retrieve those properties directly.
You could return an object that contains all the values you require.
E.G.
public class MyClass
{
public string Length { get; set; };
public string Name { get; set; };
}
Then you can return this object from your function:
public static MyClass Values()
{
MyClass myClass = new MyClass();
MyClass.Length = DAL.Util.getlength();
MyClass.Name = DAL.Util.getName(ddlID.SelectedValue);
return MyClass;
}
Then you can get whatever properties you require:
MyClass myClass = Values();
string name = myClass.Name;
Sounds like what you actually want is a struct (or a class)
public struct MyStruct
{
public string length
public string name
}
public static MyStruct Values()
{
MyStruct result;
result.name = DAL.Util.getName(ddlID.SelectedValue);
result.length = DAL.Util.getlength();
return (result);
}
Then you can look at the different elements of the struct as you like.
MyStruct data = Values();
Console.WriteLine(data.name);
Console.WriteLine(data.length);
Is there a way to get a specific element (based in index) from a string array using Property. I prefer using public property in place of making the string array public. I am working on C#.NET 2.0
Regards
Are you possibly trying to protect the original array; do you mean you want a protective wrapper around the array, through "a Property" (not of its own)? I'm taking this shot at guessing the details of your question. Here's a wrapper implementation for a string array. The array cannot be directly access, but only through the wrapper's indexer.
using System;
public class ArrayWrapper {
private string[] _arr;
public ArrayWrapper(string[] arr) { //ctor
_arr = arr;
}
public string this[int i] { //indexer - read only
get {
return _arr[i];
}
}
}
// SAMPLE of using the wrapper
static class Sample_Caller_Code {
static void Main() {
ArrayWrapper wrapper = new ArrayWrapper(new[] { "this", "is", "a", "test" });
string strValue = wrapper[2]; // "a"
Console.Write(strValue);
}
}
If I understand correctly what you are asking, You can use an indexer.
Indexers (C# Programming Guide)
Edit: Now that I've read the others, maybe you can expose a property that returns a copy of the array?
If the property exposes the array:
string s = obj.ArrayProp[index];
If you mean "can I have an indexed property", then no - but you can have a property that is a type with an indexer:
static class Program
{
static void Main()
{
string s = ViaArray.SomeProp[1];
string t = ViaIndexer.SomeProp[1];
}
}
static class ViaArray
{
private static readonly string[] arr = { "abc", "def" };
public static string[] SomeProp { get { return arr; } }
}
static class ViaIndexer
{
private static readonly IndexedType obj = new IndexedType();
public static IndexedType SomeProp { get { return obj; } }
}
class IndexedType
{
private static readonly string[] arr = { "abc", "def" };
public string this[int index]
{
get { return arr[index]; }
}
}
What you need is a Property that can have input (an index).
There is only one property like that, called an Indexer.
Look it up on MSDN.
A shortcut: use a built in code snippet: go to your class and type 'indexer' then press tab twice. Viola!
Properties don't take parameters, so that won't be possible.
You can build a method, for instance
public string GetStringFromIndex(int i)
{
return myStringArray[i];
}
Of course you'll probably want to do some checking in the method, but you get the idea.
I'm assuming that you have a class that has a private string array and you want to be able to get at an element of the array as a property of your class.
public class Foo
{
private string[] bar;
public string FooBar
{
get { return bar.Length > 4 ? bar[4] : null; }
}
}
This seems horribly hacky, though, so I'm either not understanding what you want or there's probably a better way to do what you want, but we'd need to know more information.
Update: If you have the index of the element from somewhere else as you indicate in your comment, you could use an indexer or simply create a method that takes the index and returns the value. I'd reserve the indexer for a class that is itself a container and use the method route otherwise.
public string GetBar( int index )
{
return bar.Length > index ? bar[index] : null;
}
Just return the array from the property; the resulting object will behave as an array, so you can index it.
E.G.:
string s = object.Names[15]
What you're asking can be done, like so:
You can initialize an object that holds your array, giving you exactly what you need:
public class ArrayIndexer<T> {
private T[] myArrRef;
public ArrayIndexer(ref T[] arrRef) {
myArrRef = arrRef;
}
public T this [int index] {
get { return myArrRef[index]; }
}
}
Then, in your class:
public ArrayIndexer arr;
private SomeType[] _arr;
//Constructor:
public MyClass(){
arr = new ArrayIndexer<SomeType>(ref _arr);
}
Usage:
myClassObj.arr[2] // Gives the second item in the array.
Et Voila! An indexed property.