通过"这个" C#中的引用对象

时间:2014-03-18 13:37:18

标签: c# design-patterns data-access-layer multi-tier

我需要在C#中通过引用传递this对象。但是你知道这是不可能的。 我有一个多层应用程序。简而言之,DAL从JSON格式的Web服务获取数据。必须在业务层对象中转换JSON数据。因此,我初始化Business Layer对象并将其传递给DAL。 DAL将数据转换为对象。我展示了代码的一个例子。首先是DAL:

public Stream  GetSession ( ref BusinessLayer.Session session)
{
    Stream dataStream;
    // Use the ServiceManager to build send the data to the services
    // SOAServiceManager sm = new SOAServiceManager("http://www.Test.da/authentication.json","",DataAccessLayer.HTTPMethod.POST);

    // Add the Values 
    sm.AddCriteriaValue ("name","demo");
    sm.AddCriteriaValue ("password","demo");

    // Now it's show time and the datastream is full
    dataStream = sm.CommitPost ();

    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(BusinessLayer.Session));

    session = (BusinessLayer.Session)ser.ReadObject(dataStream);

    return dataStream;
}

现在,业务层正在使用此DAL类:

namespace BusinessLayer
{
    public class Session
    {
        public bool Success { get; set; }
        public string Name { get; set; } 

        public Session ()
        {
            DataAccessLayer.Session dal_Session = new DataAccessLayer.Session ();
            dal_Session.GetSession ( ref this);
        }
    }
}

所以问题是,不能发送“this”作为参考。 所以我看到的解决方案是创建一个复制对象并将其发送到DAL,然后将其值分配给该对象。但这不是一个聪明的解决方案。 有没有办法在C#中解决这个问题?

4 个答案:

答案 0 :(得分:4)

如果您更改应用程序的结构,则绝对不需要这样做。

让DAL返回Session,而不是分配ref对象:

public BusinessLayer.Session GetSession ()
{
    //...
    return (BusinessLayer.Session)ser.ReadObject(dataStream);
}

编辑无需从构造函数中调用该方法。显然,以下仍然不起作用:

public Session ()
{
    this = dal.GetSession();
}

但是,您可以在调用此构造函数的客户端中执行调用。变化

Session session = new Session();

Session session = dal.GetSession();

或者,如果您想限制客户端和dal的耦合,您可以在Session中添加工厂方法:

public class Session
{
    //...

    public static Session GetSession()
    {
        return dal.GetSession();
    }
}

答案 1 :(得分:2)

您不应该创建新的Session对象。而是将DataContractJsonSerializer替换为Newtonsoft.Json(因为前者不公开此类方法)并使用读取JSON数据的方法和populates现有对象:

using (var reader = new Newtonsoft.Json.JsonTextReader(new StreamReader(dataStream)))
{
    var serializer = new Newtonsoft.Json.JsonSerializer();
    serializer.Populate(reader, session);
}

或者不要使用构造函数,而是使用静态工厂方法:

public class Session
{
    private Session() { }
    public static Create()
    {
        DataAccessLayer.Session dal_Session = new DataAccessLayer.Session ();
        var session = new Session();
        dal_Session.GetSession (ref session);
        return session;
    }
}

答案 2 :(得分:1)

您可以将作为参考,因为该对象是参考类型。

答案 3 :(得分:0)

C#中的任何非原语都是一直通过引用传递的。请考虑以下代码:

public static void Main()
{
    RefType r1 = new RefType();
    RefType r2 = r1;

    r1.Sprop = "hi there";

    Console.WriteLine(r2.Sprop);
}

public class RefType
{
    public string Sprop { get; set; }
}

您认为输出应该是什么?我们从未将Sprop的{​​{1}}值设置为任何值。但是r2被设置为等于r2,并且在VB.Net和C#中,这意味着r2和r1都具有指向创建的相同r1对象的相同指针。

因此,The output is "hi there"

因此,您无需使用RefType关键字传递this,因为任何可以称为ref的内容都是引用类型。