2014-12-11 3 views
4

У меня есть несколько классов, которые наследуются от разных классов. Все эти классы имеют свойство session (которое они определяют или наследуют).Как распределить свойство среди нескольких классов C#

Я хотел бы добавить свойство всех этих классов:

public SessionObject SessionObject 
{ 
    get 
    { 
     return Session["SessionObject"] as SessionObject; 
    } 
    set 
    { 
     Session["SessionObject"] = value; 
    } 
} 

Но я не вижу, каким образом.

Я думаю, что в C++ я мог бы просто использовать шаблон, но я не вижу, чтобы Generics делали это.

Как это сделать?

+0

Все ли они реализуют аналогичный интерфейс? Откуда возникает «сессия»? –

+0

интерфейсы использования, http://msdn.microsoft.com/en-us/library/87d83y5b.aspx – dotctor

+3

Интерфейс @dotctor не может реализовать setter свойства –

ответ

5

У вас есть конечное число вариантов для обмена по нескольким типам

  1. Если все ваши объекты совместно используют общий базовый класс, добавьте его там. Если они вообще не используют наследование, вы можете определить базовый класс - однако C# допускает только одно наследование наследования

  2. Использовать композицию, это включает в себя написание класса только с вашим свойством и наличие этого свойства для всех классов (см. Пример 1)

  3. методы расширения использования - вы можете сделать это на "маркер" интерфейс (без каких-либо реальных методов) или на самих объектов (пример 2)


Пример 1

public class SessionContainer 
{ 

    public SessionObject SessionObject 
    { 
     get 
     { 
      return Session["SessionObject"] as SessionObject; 
     } 
     set 
     { 
      Session["SessionObject"] = value; 
     } 
    } 
} 

public class YourClass1 
{ 
    public SessionContainer Session { get; private set; } 

    public YourClass1 
    { 
     this.Session = new SessionContainer(); 
    } 
} 

public class YourClass2 
{ 
    public SessionContainer Session { get; private set; } 

    public YourClass2 
    { 
     this.Session = new SessionContainer(); 
    } 
} 

Пример 2 (с использованием интерфейса маркера, который является пустым)

public interface ISessionContainer{} 

public static class SessionExtensions 
{ 
    public static SessionObject GetSessionObject(this ISessionContainer session) 
    { 
     return session["SessionObject"] as SessionObject; 
    } 

    public static void SetSessionObject(this ISessionContainer session, 
               SessionObject obj) 
    { 
     session["SessionObject"] = obj; 
    } 

} 

public class YourClass1 : ISessionContainer{} 
public class YourClass2 : ISessionContainer{} 
+0

. Методы расширения должны быть статическими. И метод 'SetSessionObject' должен иметь возвращаемый тип' void'. – juharr

+0

@juharr - Хороший улов, спасибо. – Jamiec

0

Создайте один базовый класс с этим свойством и сделайте его корневым классом для всех ваших классов. Создание пирамиды :-)

0

Вместо того, чтобы собственность, вы можете сделать 2 методы расширения на тип объекта:

public static class MyExtensions 
{ 
    public static void SetSessionObject(this object o, SessionObject value) 
    { 
     Session["SessionObject"] = value; 
    } 

    public static SessionObject GetSessionObject(this object o) 
    { 
     return Session["SessionObject"] as SessionObject; 
    } 
} 

Вы можете использовать его как это:

youClassInstance.GetSessionObject(); 
+3

Расширение 'object' кажется тупым – Jodrell

+0

Вам не нужно его расширять,' object' является только базовым классом каждого класса. – dario

+0

Это не скомпилируется. 'this object' отсутствует имя параметра - должен быть' этот объект obj' или аналогичный. Кроме того, 'значение' в сеттере не имеет соответствующего аргумента – Jamiec

2

несколько вариантов (при условии, что вы не можете просто сделать абстрактный класс и использовать его в качестве базового класса За все).

Используйте интерфейс и пару методов расширения:

public interface IHasSession 
{ 
    public Session Session { get; set; } 
} 

public static class HasSessionExtensions 
{ 
    public static void SetSessionObject(this IHasSession subject, SessionObject value) 
    { 
     subject.Session["SessionObject"] = value; 
    } 

    public static SessionObject GetSessionObject(this IHasSession subject) 
    { 
     return subject.Session["SessionObject"] as SessionObject; 
    } 
} 

Или использовать класс-оболочку для сеанса:

public class SessionWrapper 
{ 
    public Session Session { get; set; } 

    public SessionObject SessionObject 
    { 
     get 
     { 
      return Session["SessionObject"] as SessionObject; 
     } 
     set 
     { 
      Session["SessionObject"] = value; 
     } 
    } 
} 

И положить, что на других классов вместо:

public SessionWrapper SessionWrapper { get; set; } 

Затем вам нужно только выполнить его один раз и получить к нему доступ через:

var obj = myThing.SessionWrapper.SessionObject; 
+2

'ISessionHaver' - ужасное имя (Haver - не слово!) -' IHasSession' – Jamiec

+0

@Jamiec Это было намеренно плохое имя, указывающее на то, что интерфейс должен быть назван любым подходящим (невозможно сказать на основе контекста), но Я изменю его, чтобы успокоить ваши чувства. –

+1

Вы также можете назвать его «IBobJones»! – Jamiec