【问题标题】:C# How to assign an object returned from linq to 'this' reference?C#如何将从linq返回的对象分配给'this'引用?
【发布时间】:2013-09-02 14:15:31
【问题描述】:

好的,这就是我要解决的问题 - 我想将通过 linq 从 db 返回的对象属性分配给该对象 prperties 并获得更新任何更改的可能性,而无需在 db 中插入新行。

partial class Employee : Person
{
    public Employee(int id = 0)
    {
        if (id > 0)
            this.get(id);
    }

    public override bool get(int id)
    {
        Employee empl = db.Employees.Single(Employee => Employee.id == id);
        if (empl != null)
        {
            // here I need to do sth like
            this = empl;
            // or
            ObjectProperties.Copy(empl, this);
            return true;
        }
        else
            return false;
    }

    public override void save()
    {
        if (this.id > 0)
        {
            db.SubmitChanges();
        }
        else
        {
            db.Employees.InsertOnSubmit(this);
            db.SubmitChanges();
        }
    }

    public override void remove()
    {
        if (this.id > 0)
        {
            db.Employees.DeleteOnSubmit(this);
            db.SubmitChanges();
        }
    }
}

而且我不想让 get 方法成为静态的。

【问题讨论】:

  • 这有什么意义?您是否打算使用 ref 之类的东西来将对该实例的所有引用完全更改为另一个实例?还是只想将MyClass(如id)的所有属性更新为新值?
  • 我只想更新 MyClass 的所有属性。
  • 如果您只想更新 MyClass 的所有属性,那么您应该 a) 一次更新 MyClass 的所有属性或 b) 在 MyClass 中创建并调用一个更新所有属性的方法MyClass 一次一个或 c) 创建一个 MyClass 的新实例
  • 如果您只是想将属性复制到您的对象,那么您可以创建一个简单的方法,使用 sourceObj.GetType().GetProperties();

标签: c#


【解决方案1】:

很难为您提供一个很好的示例/建议,因为我们没有太多关于您的应用程序或最终目标用途的背景信息。但是,在发布的struct 场景之外,您不能重新分配this 引用。根据您的使用情况/应用程序,可能使用 ref 关键字可能或更正确,但如果没有有关您使用情况的更多信息,我不确定这一点。


但是,根据您只想更新类的所有属性的评论,拥有一种“CopyInfo”方法可能是最简单的,它只会复制来自另一个实例的值:

class MyClass
{
    public MyClass()
    {
        this.id = 2;
    }

    public void get()
    {
        CopyInfo(NewClass.Create());
    }

    private void CopyInfo(MyClass otherInstance)
    {
        this.id = otherInstance.id;
    }
}

另一种选择可能是将各种属性提取到接口,然后您可以围绕类的可重新分配实例创建一种包装器:

public interface MyInterface
{
    public int id { get; }
}

class MyClass : MyInterface
{
    public int id { get; private set; }

    public MyClass()
    {
        id = 2;
    }
}

那么包装类可能是:

class MyReassignableClass : MyInterface
{
    private MyClass BackingInstance;

    public int id
    {
        get
        {
            return BackingInstance.id;
        }
    }

    public void get()
    {
        BackingInstance = NewClass.create();
    }
}

您的代码可以将其视为MyInterface,但访问其成员实际上是间接访问另一个实例的成员,可以根据需要换出。

编辑:最后,我还建议您查看C# Naming Guidelines,以确保您的代码与大多数 C#.NET 代码更加一致。

【讨论】:

  • 他也可以使用sourceObj.GetType().GetProperties();创建一个通用的
  • @WiiMaxx:您可以,但如果存在可能的编译时用法,那么这可能是首选。它会更快。对于不可分配的属性(例如我的第二种情况,只有getter),它将是灵活的,可以将其设为虚拟并让派生类正确处理它们的副本,它可以处理在适用的情况下进行深度 副本(而典型的反射可能只是 副本),并且您可以忽略您不想 想要复制的属性/字段(例如我上一个示例中的BackingInstance)。对于这种情况,我认为反射不是一个好的解决方案。
【解决方案2】:

不能在类中分配this。这基本上是在告诉一个对象它不是它自己。最接近您所写内容的是Factory Method Pattern

public class CoolClass {
    public string MyProperty { get; private set; }
    public string MyOtherProperty { get; private set; }

    private CoolClass(string myProperty, string myOtherProperty) {
        MyProperty = myProperty;
        MyOtherProperty = myOtherProperty;
    }

    public static CoolClass CreateNew(string myProperty, string myOtherProperty) {
        return new CoolClass(myProperty, myOtherProperty);
    }
}

然后您可以按如下方式使用它:

var coolClass = CoolClass.CreateNew("blah", "something");

【讨论】:

    【解决方案3】:
      public class MyClass
      {
       private static MyClass myClass;
       public int Id
       {
        get
       {
        return myClass.Id;
       }
       set
       {
        myClass.Id = value;
       }
      }
    
      public static MyClass Get()
      {
       if (myClass == null)
        {
         myClass = NewClass.create();
        }
        return myClass;
      }
     }
    
     static class NewClass
     {
       public static MyClass create()
       { 
        return new MyClass();
       }
     }
    

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-08-20
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 2023-03-25
      相关资源
      最近更新 更多