Как я могу найти конкретное значение структуры?Может быть, лучший подход? - PullRequest
1 голос
/ 13 января 2012

Я пытаюсь найти структуру, созданную ранее, которая имеет определенное значение.Как только я нашел это, я хочу установить переменные в этой структуре.Я не знаю, как это сделать.Есть ли лучший способ сделать это?Может быть, занятия?Или структура должна работать?

Например, моя структура:

public struct MyTest
{
    public string device;
    public string status;
    public string revision;
    public string number;
    public string ledmo;        
}

Мой тестовый код:

MyTest thisTest=new MyTest();
thisTest.device=blah;
thisTest.number=blah2;

MyTest thisTest2=new MyTest();
thisTest2.device=blah5;
thisTest2.number=blah6;

//Another Part in my code.
//Need to find the MyTest Structure that 'device' variable = the string 'blah'
var Foundit=MyTest.find(device==blah);
Foundit.revision=blah9999;

Ответы [ 4 ]

2 голосов
/ 13 января 2012

Я бы использовал класс, потому что Изменчивые структуры - это зло

По сути, потому что каждый struct копируется, даже если вы найдете правильную структуру, вы когда-нибудь измените только одну копию. Допустим, MyTest.find находит thisTest2, что происходит это

var Foundit = MyTest.Find(device==blah); 
// The line above has made a copy of thisTest2, that copy is in FoundIt

Foundit.revision = "blah9999";
// You've changed revision in the copy of thisTest2, 
// therefore the contents of thisTest2 remain unchanged

Чтобы сделать это с классом, вам нужно будет хранить каждый экземпляр класса, который вы создаете, в списке или другой структуре данных, чтобы вы знали, что можете найти его.

Если вы сделаете это, вам также нужно сообщить списку, когда вы закончите с каждым объектом, иначе они будут зависать вечно и никогда не будут собирать мусор.

Прежде чем идти дальше, вы уверены, что это лучший способ решить эту проблему?

В любом случае, скажем, ваш класс MyData, вы можете поместить статический фабричный метод в этот вызываемый Create, который будет помещать каждый новый объект MyData в список.

public class MyData
{
    private static List<MyData> allMyDatas = new List<MyData>();
    public static IEnumerable<MyData> AllInstances
    {
        get {return allMyDatas;}
    }

    public string Device {get; set;}
    public string Status {get; set;}
    public string Revision {get; set;}
    public string Number {get; set;}
    public string Ledmo {get; set;}

    private MyData() // Private ctor ensures only a member 
    {                // function can create a new MyData
    }
    public static MyData Create()
    {
        var newData = new MyData();
        allMyDatas.Add(newData);
        return newData;
    }

    public static void Delete(MyData itemToRemove)
    {
        allMyDatas.Remove(itemToRemove);
    }
}

Везде, где вы используете MyData, вам нужно Delete, когда вы закончите с ним.

Ваш код становится

var thisTest = MyData.Create();
thisTest.Device = "blah";
thisTest.Number = "blah2";

var  thisTest2 = MyData.Create();
thisTest2.Device = "blah5";
thisTest2.Number = "blah6";

//Another Part in my code.
//Need to find the MyData Structure that 'device' variable = the string 'blah'
var Foundit = MyData.AllInstances.FirstOrDefault(md => md.Device == "blah");
if(Foundit != null)
    Foundit.Revision = "blah9999";    

Изменение FoundIt теперь также меняется thisTest

P.S .: Важно, что ничто за пределами MyData не может new экземпляр MyData. Если бы это было возможно, то был бы экземпляр MyData, который вы не смогли бы найти в AllInstances. Объявление частного конструктора означает, что будет сгенерирована ошибка компилятора, если код вне MyData попытается что-то вроде var someData = new MyData

2 голосов
/ 13 января 2012

Чтобы иметь возможность найти экземпляры объекта, созданного ранее, эти экземпляры необходимо где-то сохранить.
Одним из решений было бы поместить их в список, а затем выполнить поиск в этом списке:

var list = new List<MyTest>();

MyTest thisTest=new MyTest();
thisTest.device=blah;
thisTest.number=blah2;
list.Add(thisTest);

MyTest thisTest2=new MyTest();
thisTest2.device=blah5;
thisTest2.number=blah6;
list.Add(thisTest2);

Теперь вы можете искать, используя LINQ:

var foundItems = list.Where(x => x.device == "blah");
foreach(var foundItem in foundItems)
{
    foundItem.revision = "blah9999";
}

Обратите внимание:
Это работает только тогда, когда вы используете классы вместо структур, как указывает двоичный беспорядок в своем комментарии.

0 голосов
/ 13 января 2012

В этом случае класс будет работать лучше из-за динамического размера строки и того факта, что строк очень много.

С вашим тестовым кодом вы должны хранить List<MyTest> где-то в этом классе и добавлять thisTest и thisTest2 в список. Позже вы можете получить определенные значения (или все значения определенного device) с помощью FindAll или аналогичных методов.

List<MyTest> list = new List<MyTest>();
//add MyTests here...

var foundIt = list.FindAll(x => x.device == "blah");
0 голосов
/ 13 января 2012

Для этого вы можете использовать списки и Linq.

var test = new List<MyTest>();
//Add some items
var foundIt = test.SingleOrDefault(test => test.device == "abc");//Maximum one
if(foundIt != null)//Use a class for MyTest.
   foundIt.device = "123"
...