I want to reach the same result as I obtain in C# with this syntax, but in VB.NET:
// This is my generic object (coming from Json parsing!):
var genericContent = new { Name = "name1", Value = 0 };
// I would like to have a generic list, created by this generic item:
var myList = (new[] { genericContent }).ToList();
// So, I can add any other generic items (with the same structure)...
myList.Add(new { Name = "name2", Value = 1 });
// And treat them as a normal list, without declaring the class!
return myList.Count;
...so, I just want to create a generic array in VB.
In C# it works well, but I don't kwon this VB.NET syntax...
I'm using .NET framework 3.5!
Thank you!
No problem here:
Dim genericContent = new with { .Name = "name1", .Value = 0 }
Dim myList = {genericContent}.ToList()
myList.Add(new with { .Name = "name2", .Value = 1 })
At least in .Net 4.0 (VB.Net 10.0).
For earlier versions: No, not possible without a helper method.
I think with that framework there's no compact syntax for that, as in C#...
Try using this way...
Declare a method like this (shared is better I think):
Public Shared Function GetArray(Of T)(ByVal ParamArray values() As T) As T()
Return values
End Function
So you can create an array passing a generic parameter, than with LINQ should be easy to create a generic list:
Dim genericContent = New With { Name = "name1", Value = 0 }
Dim myList = (GetArray(genericContent)).ToList()
myList.Add(New With { Name = "name2", Value = 1 })
return myList.Count
Related
I know that in C# you can nowadays do:
var a = new MyObject
{
Property1 = 1,
Property2 = 2
};
Is there something like that in PHP too? Or should I just do it through a constructor or through multiple statements;
$a = new MyObject(1, 2);
$a = new MyObject();
$a->property1 = 1;
$a->property2 = 2;
If it is possible but everyone thinks it's a terrible idea, I would also like to know.
PS: the object is nothing more than a bunch of properties.
As of PHP7, we have Anonymous Classes which would allow you to extend a class at runtime, including setting of additional properties:
$a = new class() extends MyObject {
public $property1 = 1;
public $property2 = 2;
};
echo $a->property1; // prints 1
Before PHP7, there is no such thing. If the idea is to instantiate the object with arbitrary properties, you can do
public function __construct(array $properties)
{
foreach ($properties as $property => $value)
{
$this->$property = $value
}
}
$foo = new Foo(array('prop1' => 1, 'prop2' => 2));
Add variations as you see fit. For instance, add checks to property_exists to only allow setting of defined members. I find throwing random properties at objects a design flaw.
If you do not need a specific class instance, but you just want a random object bag, you can also do
$a = (object) [
'property1' => 1,
'property2' => 2
];
which would then give you an instance of StdClass and which you could access as
echo $a->property1; // prints 1
I suggest you use a constructor and set the variables you wish when initialising the object.
I went from c# to PHP too, so I got this working in PHP:
$this->candycane = new CandyCane(['Flavor' => 'Peppermint', 'Size' => 'Large']);
My objects have a base class that checks to see if there's one argument and if it's an array. If so it calls this:
public function LoadFromRow($row){
foreach ($row as $columnname=>$columnvalue)
$this->__set($columnname, $columnvalue);
}
It also works for loading an object from a database row. Hence the name.
Another way, which is not the proper way but for some cases okay:
class Dog
{
private $name;
private $age;
public function setAge($age) {
$this->age = $age;
return $this;
}
public function getAge() {
return $this->age;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
}
$dogs = [
1 => (new Dog())->setAge(2)->setName('Max'),
2 => (new Dog())->setAge(7)->setName('Woofer')
];
For my work I need to create a page that gets all the data for that page from a database using the kellerman framework.
The problem is that I can't seem to create a certain part.
List<TextBlockDataObject> t = new List<TextBlockDataObject>();
t.Add(new TextBlockDataObject() { Translations = (List<content new List<ContentTranslationDataObject>().Add(new ContentTranslationDataObject() { LangueageCode = "Eng", TextValue = "TestingText" } ) });
Error: Cannot implicitly convert type 'void' to
When I try to build the object trough a other way I get other errors related to bad object creation.
Other Code I used for testing
var tmpTextDataObjs = new List<TextBlockDataObject>();
tmpTextDataObjs.Add(new TextBlockDataObject());
List<ContentTranslationDataObject> ContentTransDataObject = new List<ContentTranslationDataObject>();
ContentTransDataObject.Add(new ContentTranslationDataObject() { LangueageCode = "Eng", TextValue = "this is a test.." });
tmpTextDataObjs[0].Translations = ContentTransDataObject.ToArray();
tmpPage.TextBlockDataObjects = tmpTextDataObjs.ToArray();
var titleObj = new List<ContentTranslationDataObject>();
titleObj.Add(new ContentTranslationDataObject(){LangueageCode = "Eng", TextValue = "444"});
tmpPage.TitleTranslations = titleObj.ToArray();
the code above works for a few elements but in the end the page doesn't get created.
Hope anyone can help me out!
The problem is that you are calling Add() on a newly created List object that you are trying to add to another List property. Add() returns void, not the new list.
Split up your declarations and assignments and you should be fine. Also, I recommend using the var keyword to lessen code duplication/boilerplate as well as using IList instead of List (always use a more generic type/interface when possible).
If you want to initialize the objects inline you can use the anonymous array initializer syntax.
IList<myType> myList = new[] { new myType(), new myType() };
Info myPath = new Info()
{
path = oFile.FileName
};
...
class Info
{
public string path;
public string Path
{
get { return path; }
set { path = value; }
}
}
Above is the C# code from some program and it can work normally. But I don't understand it well. The first question is that why path = oFile.FileName is not written as path = oFile.FileName; ? Why the semicolon can be removed?
The second question is that why I cannot write it like this: myPath.path = oFile.FileName ? There will give error message by Visual Studio 2012.
That construct is an object initializer. It's not a list of arbitrary statements - it's only initialization of fields and properties, and they're comma-separated:
Foo x = new Foo // Implicitly calls the parameterless constructor
{
Property1 = value1,
Property2 = value2
};
That's shorthand for:
Foo tmp = new Foo();
tmp.Property1 = value1;
tmp.Property2 = value2;
Foo x = tmp;
Object initializers were introduced in C# 3, along with collection initializers which are effectively syntactic sugar for repeated calls to Add. So:
List<string> names = new List<string>
{
"Foo", "Bar"
};
is equivalent to:
List<string> tmp = new List<string>();
tmp.Add("Foo");
tmp.Add("Bar");
List<string> names = tmp;
You have many ways of initializing an object in C#.
Here you can do what you have written, which will be an equivalent to this:
Info myPath = new Info();
myPath.Path = oFile.FileName;
this syntax
Info myPath = new Info()
{
path = oFile.FileName
};
is just a shortcut, and can be more readable, but will do the same thing. Actually it seems that it was kind of taken from VisualBasic (the With statement).
To explain the above syntax:
YourClassName <your_variable> = new YourClassName()
{
<property_name> = value,
<anotherProperty> = value,
...
<last_property> = value
};
the last way is to have a constructor that takes the path as an argument and initializes it. This is actually the way where there is the less operations done by the cpu (but it's not significant).
In C# 3.0, they added a new & helpful feature for initializing objects as a single statement/expression.
Whereas before, you'd have to issue separate statements:
Info myPath = new Info();
myPath.Filename = ...
myPath.AnotherProperty = ...
myPath.AnotherAnotherProperty = ...
You can now perform the same assignments in one step:
Info myPath = new Info
{
Filename = ...
AnotherProperty = ...
AnotherAnotherProperty = ...
};
This is especially useful, for constructing objects in Linq queries (without having to custom-code object constructors).
For example:
someList.Select(x => new SomethingElse{ SomeProperty = x.Something });
Info myPath = new Info()
{
path = oFile.FileName
};
means:
Initialize a new Info Class and add to property path the value oFile.FileName
it is the short version of:
Info myPath = new Info();
myPath.path = oFile.FileName;
you do not need ';' because you can stack more properties in the brackets like this:
Person p = new Person()
{
Name = "John",
Age = 25
};
C# allows you to initialize properties of an object at the same time that you're constructing it.
These are all equivalent:
var foo = new Foo();
foo.Property = "Bar";
foo.AnotherProperty = 12;
var foo = new Foo()
{
Property = "Bar",
AnotherProperty = 12
};
// The parentheses are not really necessary for parameterless constructors
var foo = new Foo
{
Property = "Bar",
AnotherProperty = 12
};
It is the new way of initializing variables in C#. You can also skip '()' signs.
You can initialize like that also lists, arrays, etc. in brackets you must insert elements which you want to initialize in your object.
Info myPath = new Info()
{
path = oFile.FileName
};
is equivalent to
Info myPath = new Info();
myPath.path = oFile.FileName;
When initializing with the object initializing structure, you create a list of property assignments as you noted. This way you can create objects and assign variables in one call without having an explicit constructor. The above could easily have been written in one line.
More info can be found on the MSDN website.
ASP.NET 3.5 C#
I am joining two tables using Linq.
Table names are MapAssets and ExitPoint.
In Database they are related with 'has a relationship'
I am writing a function in my BLL to return the joined table
public List<ExitPoints> GetExitPointDetailsByProjectID(int iProjectID)
{
ctx = new CoreDBDataContext();
var exitPointDetails = from ma in ctx.MapAssets
join ep in ctx.ExitPoints
on ma.MapAssetID equals ep.MapAssetID
where ma.ProjectID == iProjectID
select new
{
//would like to have data from both tables here
ctx.MapAssets,
ctx.ExitPoints
};
return exitPointDetails.ToList();
}
This obviuosly doesn't work. And I dont know what to return at all.
All constraint I have for the return is to be able to be bound to a gridview.
is this the correct way? Or else whats the correct way?
You can't, or better, the only way is to return them boxed in a List of object, but this hugely complicates things, because you can't cast them to any type (of course it's anonymous) and you can only access their properties through reflection....
In cases like that, I'd highly suggest you to create a custom class.
EDIT:
On a side note...
If you were using .net 4, things would be easier because you could returns dynamic Type instead of object (look at this link to see dynamic's simplifications), but I'd prefer to create a custom class anyway.
Have a look at how to return anonymous types from Method.
http://forums.asp.net/t/1387455.aspx.
Copying the code from the link.
object ReturnAnonymous()
{
return new { Name="Faisal", City="Chakwal" };
}
// Application entry-point
void Main()
{
object o = ReturnAnonymous();
// This call to 'Cast' method converts first parameter (object) to the
// same type as the type of second parameter - which is in this case
// anonymous type with 'Name' and 'City' properties
var typed = Cast(o, new { Name="", City="" });
Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City);
}
// Cast method - thanks to type inference when calling methods it
// is possible to cast object to type without knowing the type name
T Cast<T>(object obj, T type)
{
return (T)obj;
}
You can use the method mentioned below to return List and
List<object> lstAnonymousTypes = GetExitPointDetailsByProjectID(1);
foreach(object o in lstAnonymousTypes)
{
//Change it accordingly
var typed = Cast(o, new { new MapAssets() , new ExitPoints() });
}
Hope this helps not tried.
You can't return an anonymous type, you can only use an anonymous type in the scope of the method it's in. You could need to create a new class with MapAssets/ExitPoints properties and select a new instance of that class.
You are trying to return List ExitPoints and List of MapAssets which is not possible because you are getting the output from both tables ie ExitPoints and MapAssets. And it is also not possible to return an anonymous type. So in order to retrun the query create a class name ExMapClass with properties that you need as output of the queries. Now after executing the linq query which you have written iterate it ie
create list of newly created class
list newclass = new list ();
foreach( var result in ctx )
{
instantiate the created class
obj.Property1 = var.MapAssets;
obj.Property2 = var.ExitPoints;
newclass.add(obj);
}
now retrun the list of newlycreated class.
hope you got it.
Do you have to bind to this object after you've created it? If not then you can create an "persistent AnonymousType" class that stores the values in a dictionary and returns the property values with a method like:
string lastName AnonType.GetValue<string>("LastName");
int age AnonType.GetValue<int>("Age");
Here is a link to an excellent example. The author also has an example where he creates the "AnonymousType" from a datatable.
I have worked on a variation of this where I provide the ability to query a list of "AnonymousType" with the following syntax:
// Here's the query
var dept13 = anonAgents.AsQueryable()
.Where(x => x.Has("Department", Compare.Equal, 13);
// Here is how the List is constructed
private static AnonymousType ProvisionAgent(string name, int department)
{
return AnonymousType.Create(new
{
Name = name,
Department = department
});
}
private List<AnonymousType> CreateAnonAgentList()
{
var anonAgents = new List<AnonymousType>();
// Dave and Cal are in Department 13
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Dan Jacobs", 13, 44)));
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Calvin Jones", 13, 60)));
// Leasing = Dept 45
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Stanley Schmidt", 45, 36)));
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Jeff Piper", 45, 32)));
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Stewart Blum", 45, 41)));
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Stuart Green", 45, 38)));
// HR = Dept 21
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Brian Perth", 21, 25)));
anonAgents.Add(AnonymousType.Create(CreateAgentAnonType("Katherine McDonnel", 21, 23)));
return anonAgents;
}
Just use and ArrayList
public static ArrayList GetMembersItems(string ProjectGuid)
{
ArrayList items = new ArrayList();
items.AddRange(yourVariable
.Where(p => p.yourProperty == something)
.ToList());
return items;
}
wont this work ?
ctx = new CoreDBDataContext();
var exitPointDetails = from ma in ctx.MapAssets
join ep in ctx.ExitPoints
on ma.MapAssetID equals ep.MapAssetID
where ma.ProjectID == iProjectID
select Tuple.Create(ma, ep);
return exitPointDetails.ToList();
I have a function that returns this object:
var result = AjaxUserToPlacePaging();
//this is the object
object[] objcs = new object[1];
objcs[0] = new
{
countHereNow = countHereNow.ToString(),
countWillBeHere = countWillBeHere.ToString(),
countWasHere = countWasHere.ToString()
};
How can I extract the information from the object?
for example
int count = result[0].countHereNow;
the resun i nned the function to be object is because
i using jquery
and with the jquery it takes the object and converting it into json
You will need to use Reflection:
string countHereNow = string.Empty;
Type objType = result[0].GetType();
PropertyInfo prop = objType.GetPropertyInfo("countHereNow");
countHereNow = prop.GetValue(result[0], null) as string ?? string.Empty;
Typically I think returning an anonymous type is a bad idea, but maybe you have a reason for it. Otherwise, I would create a custom class and just return an array of that class type.
I recommend making a custom class, and storing that, instead of just storing an anonymous type into an "object" directly.
objcs[0] = new MyClass
{
countHereNow = countHereNow.ToString(),
countWillBeHere = countWillBeHere.ToString(),
countWasHere = countWasHere.ToString()
};
That will allow you to cast it back, when you retrieve:
MyClass myClass = result[0] as MyClass;
if (myClass != null)
{
int count = myClass.countHereNow;
}
There are tricks you can do to work with anonymous types, but in most cases, they just make the code less maintainable.
You need to use reflection (or something that uses reflection) to get the contents of your anonymous object outside the function where you create it. Maybe you should create a class and return instances of that instead?
You're currently declaring the array as an object array
object[] objcs = new object[1];
Declare it as a implicitly typed (var) array
var objcs = new [];
That way the objects you actually adding to the array won't be of SystemObject type but will be implicitly typed