If you are trying to mutate the object in-place, you can "fake it" with a slightly nicer syntax by employing an extension method like this:
public delegate void Mutator<T>(ref T arg) where T : struct;
public static void FindAndMutate<T>(
    this IList<T> self,
    Predicate<T> predicate,
    Mutator<T> mutator) where T : struct
{
    if (self == null) { throw new ArgumentNullException("self"); }
    if (predicate == null) { throw new ArgumentNullException("predicate"); }
    if (mutator == null) { throw new ArgumentNullException("mutator"); }
    for (int i = 0; i < self.Count; ++i) {
        var value = self[i];
        if (predicate(value)) {
            mutator(ref value);
            self[i] = value;
        }
    }
}
The usage would look something like this:
struct AStruct
{
    public string String;
    public int Int;
}
var list = new[] {
    new AStruct() { String = "hello", Int = 0},
    new AStruct() { String = "world", Int = 1}
};
list.FindAndMutate(i => i.Int == 0, (ref AStruct i) => i.String = "goodbye");
This is obviously not a perfect solution, and does involve copying of the struct inside of the extension method.
Really, if you need reference semantics you should be using a reference type instead of a value type.