C# - How To Check Object Type Using If Statement - object

i'm currently writing an application with a parent class named 'Vehicle' and two children classes named 'Car' and 'Truck'. My problem is that I would like to search through the full list of Vehicles and return only each car, or each truck depending on what object is placed into a method. Right now I have had to write a method for ach search term such as below:
public string searchCarsByName(string nameString)
{
string carNames = "";
foreach (Car car in Vehicles.OfType<Car>())
{
if (car.Name.Contains(nameString))
{
carNames += car.ToString();
}
}
if (carNames == "")
{
return "No cars found";
}
else
{
return carNames;
}
}
public string searchTrucksByName(string nameString)
{
string truckNames = "";
foreach (Truck truck in Vehicles.OfType<Truck>())
{
if (truck.Name.Contains(nameString))
{
truckNames += name.ToString();
}
}
if (truckNames == "")
{
return "No vehicle found";
}
else
{
return truckNames;
}
}
My only problem is that the names isn't the only way I would like to search, so for each search I am going to perform then I will have to write two methods. What i'm looking for is a way to pass in an Object to the method, and then dependent on the object it will append the necessary details to the string such as below:
public string searchVehiclesByName(Vehicle nameString)
{
string vehicleNames = "";
if(Vehicle.Type == car)
{
foreach (Car car in Vehicles.OfType<Car>())
{
if (car.Name.Contains(nameString))
{
vehicleNames += car.ToString();
}
}
}
else
{
foreach (Truck truck in Vehicles.OfType<Truck>())
{
if (truck.Name.Contains(nameString))
{
vehicleNames += truck.ToString();
}
}
}
if (vehicleNames == "")
{
return "No vehicles found";
}
else
{
return vehicleNames;
}
}
}
Essentially what I need is a way to pass in a parent object and check if an object is of a certain child type before creating the resultant string, rather than having to pass each individual type of child object into a method to get the results I want.
Thank you in advance.

Please have a look at this: Type Checking: typeof, GetType, or is?
public string searchVehiclesByName(Vehicle vehicle)
{
string vehicleNames = "";
if(vehicle.GetType() == typeof(Car))
{
foreach (Car car in Vehicles.OfType<Car>())
{
if (car.Name.Contains(nameString))
{
vehicleNames += car.ToString();
}
}
}
else
{
foreach (Truck truck in Vehicles.OfType<Truck>())
{
if (truck.Name.Contains(nameString))
{
vehicleNames += truck.ToString();
}
}
}
if (vehicleNames == "")
{
return "No vehicles found";
}
else
{
return vehicleNames;
}
}
Hope this helps.

Related

How to do string concatenate inside viewmodel observe?

So the Categories here is a List<Category> which has id and name attribute. I want to concat all of category.name elements in the list before I bind it to view. But the categoryString still "".
private fun getData(id: Int){
buyerViewModel.getProductDetail(id).observe(viewLifecycleOwner){
it.data.let { data ->
var categoryString = ""
data?.Categories?.forEachIndexed { index, category ->
if(index == data?.Categories.size - 1){
categoryString.plus(category.name)
} else {
categoryString.plus(category.name + ", ")
}
}
binding.apply {
Glide.with(requireContext()).load(data?.image_url).into(vpImage)
tvItemNama.text = data?.name
tvItemCategory.text = categoryString
tvItemHarga.text = data?.base_price!!.toRp()
tvDeskripsi.text = data.description
}
}
}
}

Windows Form in a Revit Addin

I have written quite a few different add-ins now but I keep struggling to get a windows form working on Revit. The program builds fine and I have the dll set up for Revit to access.
Here are the different sections of my code. The program is more extensive than what is seen but I believe that the problem is a reference issue or a problem with my ADDIN file. Maybe there is a different way I need to set up my ADDIN file since I have a windows form in it?? Let me know.
Here is a Dropbox folder with the screenshots in it.
Let me know if there is anything else you need to see. The error in Revit says it has to do with the FullName but I believe I put it in the ADDIN file correctly, and I did it the same as I had for other ADDINs.
Thank you for your help!
[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class CicuitChecker : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
//set document variable
Document document = commandData.Application.ActiveUIDocument.Document;
using (Transaction trans = new Transaction(document))
{
trans.Start("Circuit Checker");
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
//run through looped form in case of user not selecting needed fields, and store what family the user wants the program to check
Boolean messedUp = false;
Boolean All = false, lightF = false, recep = false, elecEquip = false, equipCon = false, junc = false, panels = false;
FilteredElementCollector collector = new FilteredElementCollector(doc), collector2 = new FilteredElementCollector(doc);
while (messedUp)
{
CircuitChecker.CircuitCheckerForm form = new CircuitChecker.CircuitCheckerForm();
form.ShowDialog();
//Get application and document objects
foreach (String item in form.getSelectionElementsLB())
{
if (item.Equals("All"))
{
All = true;
break;
}
else if (item.Equals("Lighting Fixtures"))
{
lightF = true;
}
else if (item.Equals("Recepticales"))
{
recep = true;
}
else if (item.Equals("Electrical Equipment (including Panels)"))
{
elecEquip = true;
}
else if (item.Equals("Junctions"))
{
junc = true;
}
else
{
messedUp = true;
TaskDialog.Show("Error", "At least one element must be selected.");
}
}
if (form.getSelectionPlaceLB().Equals("Entire Project"))
{
collector
= new FilteredElementCollector(doc)
.WhereElementIsNotElementType();
collector2
= new FilteredElementCollector(doc)
.WhereElementIsNotElementType();
}
else if (form.getSelectionPlaceLB().Equals("Elements in Current View"))
{
collector
= new FilteredElementCollector(doc, document.ActiveView.Id)
.WhereElementIsNotElementType();
collector2
= new FilteredElementCollector(doc, document.ActiveView.Id)
.WhereElementIsNotElementType();
}
else
{
messedUp = true;
TaskDialog.Show("Error", "A place must be selected.");
}
}
Color color = new Color(138, 43, 226); // RGB
OverrideGraphicSettings ogs = new OverrideGraphicSettings();
OverrideGraphicSettings ogsOriginal = new OverrideGraphicSettings();
ogs.SetProjectionLineColor(color);
int notCircuited = 0;
//ElementId symbolId = family
ElementCategoryFilter lightFilter = new ElementCategoryFilter(BuiltInCategory.OST_LightingFixtures);
ElementCategoryFilter recepFilter = new ElementCategoryFilter(BuiltInCategory.OST_ElectricalFixtures);
ElementCategoryFilter elecEquipFilter = new ElementCategoryFilter(BuiltInCategory.OST_ElectricalEquipment);
//ElementClassFilter filter = new ElementClassFilter(typeof("Junction Boxes - Load"));
//FamilyInstanceFilter juncFilter1 = new FamilyInstanceFilter(doc, );
LogicalOrFilter first = new LogicalOrFilter(lightFilter, recepFilter);
if (All)
{
collector.WherePasses(first);
IList<Element> allArr = collector.ToElements();
foreach (Element e in allArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
collector2.WherePasses(elecEquipFilter);
IList<Element> elecEquipArr = collector.ToElements();
foreach (Element e in elecEquipArr)
{
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_SUPPLY_FROM_PARAM).AsString();
if ((panel.Equals("")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
TaskDialog.Show("Circuit Checker", notCircuited + " lighting fixtures are not circuited in this view.");
trans.Commit();
}
if (!trans.HasEnded())
{
if (lightF)
{
collector.WherePasses(lightFilter);
IList<Element> lightArr = collector.ToElements();
foreach (Element e in lightArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (recep)
{
collector.WherePasses(recepFilter);
IList<Element> recepArr = collector.ToElements();
foreach (Element e in recepArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (elecEquip)
{
collector.WherePasses(elecEquipFilter);
IList<Element> elecEquipArr = collector.ToElements();
foreach (Element e in elecEquipArr)
{
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_SUPPLY_FROM_PARAM).AsString();
if ((panel.Equals("")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (junc)
{
collector.WherePasses(recepFilter);
IList<Element> juncArr = collector.ToElements();
foreach (Element e in juncArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
TaskDialog.Show("Circuit Checker", notCircuited + " lighting fixtures are not circuited in this view.");
trans.Commit();
}
}
return Result.Succeeded;
}
public static Boolean IsNumeric(Object Expression)
{
if (Expression == null || Expression is DateTime)
return false;
if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
return true;
try
{
if (Expression is string)
Double.Parse(Expression as string);
else
Double.Parse(Expression.ToString());
return true;
}
catch { } // just dismiss errors but return false
return false;
}
}
This code is having the functionality in the 'main class.' I have since moved the functionality to the form class as konrad suggested but am still receiving the FullClassName error in Revit. Please Help!
The schedule data add-in provides a full Visual Studio solution demonstrating how to display a Windows form in a Revit add-in, including the generation of the Windows form on the fly:
http://thebuildingcoder.typepad.com/blog/2012/05/the-schedule-api-and-access-to-schedule-data.html
Here's how I usually set up my Windows Forms based External Commands. Remember that you have to create an External Command, and your addin manifest must point at this class. Then from this class you can launch the Form like so:
[Transaction(TransactionMode.Manual)]
public class SomeCommand : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
// Get application and document objects
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
UIDocument uidoc = uiApp.ActiveUIDocument;
try
{
SomeNamespace.SomeForm form = new SomeNamespace.SomeForm(doc);
form.ShowDialog();
return Result.Succeeded;
}
// Catch any exceptions and display them
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
So I have a Form class that I instantiate from my ExternalCommand and pass Document to its constructor. That way I have access to document when I am interacting with the form later. I wire up all functionality in code behind of the Form.
Agree, the OP's question is why doesn't the addin work...
From looking at the images, it seems like the issue is that Revit is not properly finding the full class name of the command.
It's a little unusual that you don't have your command class wrapped in a namespace (your form class is, for example).
I would recommend wrapping it in a namespace like "circuitchecker" - like your form class.
Then the "full name" in the addin file would become "circuitchecker.circuitchecker"
(the namespace.classname) - this helps Revit distinguish different classes that might have the same name.
side note: I don't believe that putting a URL into the Image/LargeImage fields in the addin will work - but not positive.

Multi-valued mappings in Solidity

I need to be able to have several possible values under the same key in a mapping. Today, Solidity's mappings are mono-valued: writing a value overwrite the previous one (which is still in the blockchain, but not retrievable by a contract). I wrote this code to have multi-valued mappings:
contract MVM {
struct Bucket {
bool exists;
uint num; // Never decreases: we can only add records, not remove them.
mapping(uint => Record) records;
}
struct Record {
bool exists;
string info;
}
// Do not make it public: the compiler crashes when generating
// accessors https://github.com/ethereum/solidity/issues/633
mapping(string => Bucket) data;
function set(string key, string value) {
if (data[key].exists) {
data[key].records[data[key].num] = Record(true, value);
}
else {
data[key].exists = true;
data[key].records[0] = Record(true, value);
}
data[key].num++;
}
function num_of(string key) returns (uint) {
return data[key].num; // Guaranteed to be initialized as zero?
}
function get(string key, uint index) returns (string) {
if (!data[key].exists || !data[key].records[index].exists) {
throw;
}
return data[key].records[index].info;
}
}
An example of its use from the geth console:
> mvs.set.sendTransaction("foo", "bar", {from:eth.accounts[0], gas: 1000000})
"0x79c52c437a94f3301775acec5639404eff563fce1a99ad097f5db28f109d7ab5"
> mvm.set.sendTransaction("foo", "thing", {from:eth.accounts[0], gas: 1000000})
"0xb26b8d34691b0da5cb48af68933e81b514199f4ed8bd2b557767c8b55da85f50"
> mvm.get.call("foo")
"bar"
> mvm.get.call("foo", 1)
"thing"
> mvm.num_of.call("foo")
2
Is there a flaw in my approach? Or a better solution?
contract MVM {
struct Record {
bool exists;
string info;
}
mapping(string => Record[]) data;
// If you want to iterate the whole thing, you can use this:
string[] keysNames;
function set(string key, string value) {
// Remove this if, if you don't need iteration
if (data[key].length == 0) {
keysNames.push(key);
}
data[key].push(Record(true, value));
}
function num_of(string key) constant returns (uint) {
return data[key].length;
}
function get(string key, uint index) constant returns (string) {
if (data[key][index].exists == false) {
throw;
}
return data[key][index].info;
}
function exampleIterate() constant returns (string last) {
uint keysLen = keysNames.length;
for(uint i = 0; i < keysLen; i++) {
uint recordsLen = data[keysNames[i]].length;
for(uint j = 0; j < recordsLen; j++) {
last = data[keysNames[i]][j].info;
}
}
}
}

Generic method named Max that takes 2 parameters and returns greater of 2 reference types

In C# Language Write a generic method named Max that takes 2 parameters and returns greater of 2 values. Apply constraint to support only reference types.Test it against Employee class which has salary as the property of type int.Max should compare two employee instances based on the salary and return employee instance which has greater salary.
This is what I have done How should i proceed further...?
using System;
using System.Collections.Generic;
using System.Text;
namespace Generic_Max_of_Salary
{
class Program
{
static void Main(string[] args)
{
runtest();
}
public static void runtest()
{
Test_Maximum(new Employee { Salary = 10000 }, new Employee { Salary = 20000 }, new Employee { Salary = 20000 }, 1);
Test_Maximum(new Employee { Salary = 30000 }, new Employee { Salary = 20000 }, new Employee { Salary = 30000 }, 2);
Test_Maximum(new Employee { Salary = 10000 }, new Employee { Salary = 10000 }, new Employee { Salary = 10000 }, 3);
}
public static void Test_Maximum(Employee emp1, Employee emp2, Employee obtained_answer, int testcase)
{
Employee expected_answer = Maximum<Employee>(emp1, emp2);
if (CompareTo(obtained_answer, expected_answer))
{
Console.WriteLine("Test " + testcase + " Passed");
}
else
{
Console.WriteLine("Test " + testcase + " Failed");
}
}
public static T Maximum<T>(T emp1, T emp2)
{
if (emp1.Salary >= emp2.Salary)
{
return emp1;
}
else
{
return emp2;
}
}
public static bool CompareTo(Employee obtained_answer, Employee expected_answer)
{
if (obtained_answer.Salary == expected_answer.Salary)
{
return true;
}
else
{
return false;
}
}
}
class Employee
{
public int Salary { get; set; }
}
}
That's because the compiler does not know that the open type T has a property called Salary. You can either add a constraint to T that it needs to be a derived class of Employee or you need to call the Maximum function with the salaries instead of the employee instances.
public static T Maximum<T>(T emp1, T emp2) where T: Employee
{
if (emp1.Salary >= emp2.Salary)
{
return emp1;
}
else
{
return emp2;
}
}
Just to elaborate on the question, a generic function only constraining on reference type like
static T Maximum<T>(T obj1, T obj2) where T : class
{
if (obj1 > obj2)
{
return obj1;
}
return obj2;
}
does not work as the > operator is not defined on T. Your best chance is to check if the input objects are IComparable or Employees:
static T Maximum<T>(T obj1, T obj2) where T : class
{
if (obj1 is Employee && obj2 is Employee)
{
if (((Employee)obj1).Salary > ((Employee)obj2).Salary)
{
return obj1;
}
return obj2;
}
if (obj1 is IComparable && obj2 is IComparable)
{
if (((IComparable)obj1).CompareTo(obj2) > 0)
{
return obj1;
}
return obj2;
}
throw new NotSupportedException("Cannot compare two reference types without knowledge of the type.");
}

rms queries, find a phrase inside a text

I want to do a midlet application for save product with its bar code, product's name, product's description and price. Then it is going to be saved as it:
123123123-coca cola-soda-6.50
124512341-crystal coca-soda-7.00
well for this I have built this code:
public boolean ProductoAgregar(String dato) // add product
{
byte bytes[] = dato.getBytes();
try {
rs.addRecord(bytes, 0, bytes.length);
return true;
} catch (RecordStoreException ex) {
ex.printStackTrace();
return false;
}
}
public boolean ProductoModificar(String dato, int id) // update product
{
try
{
byte bytes[] = dato.getBytes();
rs.setRecord(id, bytes, 0, dato.length());
return true;
}
catch(Exception ex)
{
return false;
}
}
public boolean ProductoEliminar(int id)// delete product
{
try
{
rs.deleteRecord(id);
return true;
}
catch(Exception ex)
{
return false;
}
}
I don't have an idea for how to create the method for find a product (with a part of its name, or with its bar code) and what is going to return? maybe an array?
For example all products has write coca in its name (or in description) or
find a unique product with bar code.
(This is a class with I'll instance for use its methods)
you can try following code, by editing as per your usage. I am using below code for searching an item from RMS Data.
public boolean SearchRecord(String Rec, int pos )
{
String [] data = getRecordData();
Rec = Rec.substring(0,pos);
for ( int i = 0 ; i < data.length ; i++ )
{
data[i] = data[i].substring(0, pos );
if ( Rec.toString().trim().equals(data[i].toString().trim()) )
{
data = null; // System.gc();
return true;
}
}
data = null; // System.gc();
return false;
}
By Changing the value of "pos" variable you can achieve your goal.

Resources