有什么方法可以推断操作类型或完整的操作吗?

发布于 2024-10-05 19:02:27 字数 2213 浏览 0 评论 0原文

我发现自己(也)经常使用如下所示的构造:

class MyClass
{
    public TypeA ObjectA;
    public TypeB ObjectB;
    public TypeC ObjectC;
    public List<TypeD> ListOfObjectD = new List<TypeD>();

    public void DoSmth()
    {
        return SomeConstruct(
            /*...*/
            new Setter<TypeA>(a => ObjectA = a), // these are the
            new Setter<TypeB>(b => ObjectB = b), // things I'm trying
            new Setter<TypeC>(c => ObjectC = c), // to make shorter
            new Setter<TypeD>(d => ListOfObjectD.Add(d)),
            /*...*/
        );
    }
}
class Setter<T>
{
    public Action<T> Action;

    public Setter(Action<T> action)
    {
        Action = action;
    }
}

Setter 类是否有任何方法可以推断 Action 的类型并创建标准 (T obj) => Member = obj 仅通过某种方式传递 Member 来执行操作?我正在考虑类似的事情:

new Setter(ObjectA)

这当然不是有效的语法,但应该让您了解我想要实现的目标。我在代码中使用这个构造数百时间,所以代码 这个小小的改变所节省的费用将是巨大的。


编辑:添加了 TypeD 示例。该部分

new Setter<TypeD>(d => ListOfObjectD.Add(d))

可以简化为

new Setter<TypeD>(ListOfObjectD.Add)

很棒的部分,因为它减少了冗余代码。如果也能被推断出来那就完美了。我正在为其他人寻找类似的东西。

@Lazarus - 基本上目的是返回 setter,因此其他对象可以设置类的某些成员(或者可以执行 Action 中定义的其他内容),而无需访问类本身,仅访问 Setter 对象。完整的原因列表又长又复杂,但该程序的结构就像一个魅力,我怀疑是否需要改变(当然,这个例子是简化的,实际上并没有什么意义)。


编辑2:我找到了一个简化列表的好方法:

static class SetterHelper
{
    public static Setter<T> GetSetter<T>(this List<T> list)
    {
        return new Setter<T>(list.Add);
    }
}

现在我可以使用这个:

ListOfObjectD.GetSetter()

效果非常好!为什么我不能直接对 T 做同样的事情?我尝试了这个:

static class SetterHelper
{
    public static Setter<T> GetSetter<T>(this T item)
    {
        return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
    }
}

当然它不会按预期工作,因为它会设置项目,但不会设置传递的成员。我尝试将 ref 添加为 (ref this T item) 但它不会编译:(...这本来就很完美。

I find myself (too) often using a construct like the following:

class MyClass
{
    public TypeA ObjectA;
    public TypeB ObjectB;
    public TypeC ObjectC;
    public List<TypeD> ListOfObjectD = new List<TypeD>();

    public void DoSmth()
    {
        return SomeConstruct(
            /*...*/
            new Setter<TypeA>(a => ObjectA = a), // these are the
            new Setter<TypeB>(b => ObjectB = b), // things I'm trying
            new Setter<TypeC>(c => ObjectC = c), // to make shorter
            new Setter<TypeD>(d => ListOfObjectD.Add(d)),
            /*...*/
        );
    }
}
class Setter<T>
{
    public Action<T> Action;

    public Setter(Action<T> action)
    {
        Action = action;
    }
}

Is there any way for the Setter class to infer the type of the Action and create the standard (T obj) => Member = obj Action by only passing the Member in some way? I'm thinking of something like:

new Setter(ObjectA)

which of course is not valid syntax, but should give you an idea what I'm trying to achieve. I'm using this construct literally hundreds of time in my code, so the code
saved by this small change would be tremendous.


Edit: Added the TypeD example. The part

new Setter<TypeD>(d => ListOfObjectD.Add(d))

can be simplified to

new Setter<TypeD>(ListOfObjectD.Add)

which is awesome because it cuts from the redundant code. If only <TypeD> could also be inferred it would be perfect. I'm looking for something like this for the others.

@Lazarus - basically the purpose is to return setters, so other objects can set certain members of the class (or it can do other stuff defined in the Action) without accessing the class itself, only the Setter object. The full list of reasons is long and convoluted, but the structuring of the program works like a charm and I doubt needs changing (the example of course is simplified and doesn't really make sense as is).


Edit 2: I found a good way to simplify things for List's:

static class SetterHelper
{
    public static Setter<T> GetSetter<T>(this List<T> list)
    {
        return new Setter<T>(list.Add);
    }
}

Now I can just use this:

ListOfObjectD.GetSetter()

which works perfectly! why can't I do the same for T directly? I tried this:

static class SetterHelper
{
    public static Setter<T> GetSetter<T>(this T item)
    {
        return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
    }
}

Of course it won't work as intended because it will set item, but not the passed member. I tried adding ref as (ref this T item) but it won't compile :(... It would have been perfect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧夏天 2024-10-12 19:02:27

我能为您提供的最好的语法是以下语法:

Setter.For( () => ObjectA );

使用此帮助程序类

static class Setter
{
    public static Setter<T> For<T>(Expression<Func<T>> e)
    {
        ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
        Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();

        return new Setter<T>(s);
    }
}

Best I can offer you is the following syntax:

Setter.For( () => ObjectA );

using this helper class

static class Setter
{
    public static Setter<T> For<T>(Expression<Func<T>> e)
    {
        ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
        Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();

        return new Setter<T>(s);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文