How can I persist information about an object afte

2019-06-24 14:54发布

问题:

I've been asking questions about what I think might be solutions, but somebody pointed out that I'm falling into the XY problem and that I should just ask about my exact problem.

I have a struct that I want other people to be able to use in their own programs. It needs to be possible to implicitly convert to this type from other existing types but at the same time some information needs to persists after this assignment. Here's a simple example of the issue:

using System;
public struct MyStruct {
    public string SomethingImportant;
    public MyStruct(string s) {
        SomethingImportant = s;
    }

    //this function needs to have no knowledge of how/where the struct is being used
    public bool SomeFunction(string s) {
        return s == SomethingImportant;
    }

    public static implicit operator MyStruct(double x) {
        return new MyStruct();
    }
}
public class MyClass {
    MyStruct child = new MyStruct("important");

    public MyClass() {
        //prints out "important"
        Console.WriteLine(child.SomethingImportant);
        child = 7.5;
        //prints out ""
        Console.WriteLine(child.SomethingImportant);
    }
}

After the struct is replaced with a new struct from the implicit conversion, the information stored in SomethingImportant is lost. This would be a natural place for overloading the assignment operator but, unfortunately, this isn't possible in c#.

My thoughts turned to attributes because the extra information does not need to be modified after the initial declaration of the object and it would be mostly acceptable if the persistence was restricted to fields of classes. It seems like this isn't a viable option because the struct can't access attributes associated with it unless it knows what type it lives within.

Is there any way to accomplish something remotely like this in c#? I know that adding an explicit update function like MyStruct.Update(double x) would give the desired behavior but, based on how the library functions, this would be a huge burden on users in terms of rewriting large amounts of existing code. I would much rather do something messy, unsafe, or obscure in my own code than require so much rewriting for library users.

Thanks for any thoughts!

回答1:

I'd say this isn't possible at all, given that "something important" isn't equal for all MyStruct instances (in which case the trivial solution is to make it static).

The implicit conversion creates a new object which cannot know anything about which variable it is assign to, not even if it is assigned at all. So you cannot access any data from that variable.

Perhaps the idea you had with attributes is worth pursuing, that is, moving the tagging one level up in your class hierarchy.

To clarify my point, what is the expected output from this:

public class MyClass
{
    public MyClass() 
    {
        MyStruct child1 = new MyStruct( "abc" );
        // should print "abc"
        Console.WriteLine(child1.SomethingImportant);

        MyStruct child2 = 7.5;
        // should print out what?
        Console.WriteLine(child2.SomethingImportant);

        MyStruct child3 = new MyStruct( "cde" );
        child3 = 5.7;
        // will never, ever print "cde" (if not static)
        Console.WriteLine(child2.SomethingImportant);
    }
}

but this will work:

public MyOtherClass
{
    public MyStruct TheChild;
    public string SomethingImportantAssociatedToTheChild;
}

[...]

MyOtherClass a;
a.SomethingImportantAssociatedToTheChild = "abc";
a.TheChild = 7.5;