2013-05-04 2 views
1

мне нужно разделить некоторые общие функциональные возможности между двумя статическими классами:Share общие функциональных возможностей между двумя статическими классами

public static class Class 
{ 
    public static void ClassMethod() 
    { 
     SharedMethod<object>(); 
    } 


    //ideally a private method 
    internal static void SharedMethod<T>() 
    { 

    } 
} 

public static class GenericClass<T> 
{ 
    public static void GenericClassMethod() 
    { 
     SharedMethod<T>(); 
    } 
} 

Есть ли лучший дизайн здесь? internal - мой последний выбор, но действительно метод SharedMethod не имеет значения за пределами этих двух классов.

Требования:

  1. Я не могу объединить их в один класс, мне нужно их по отдельности, один общий и другой нет.

  2. Классы не обязательно должны быть строго статичными, но они не должны быть реалистичными или наследуемыми.

  3. SharedMethod может упасть в любом классе, это не имеет значения.

+3

Какова техническая причина, по которой их нельзя комбинировать? в частности, я думаю о одном статическом классе с комбинацией общих и не общих методов, для exmaple –

+0

@MarcGravell его более семантические причины. 'Class' и' GenericClass <> 'связаны друг с другом, и они служат схожим целям, но идея передается лучше, если их разделять. Его больше похожи на «Tuple» и «Tuple <>» и т. Д. – nawfal

+0

@nawfal Обычно мне нравятся абстрактные вопросы архитектуры программного обеспечения, но я думаю, что никто не сможет помочь вам, не уточняя, что представляют собой ваши классы, какие операции они имеют (и что такое общий) и как они должны использоваться в приложении. Пример 'Tuple' и' Tuple <> 'слишком тривиален, потому что можно просто определить' public class Tuple: Tuple '(поскольку он не является статическим). У C# нет 'друзей', поэтому' internal' (будь то внутренний класс или внутренний метод), вероятно, ваш лучший выбор. – dialer

ответ

1

Это обходное решение не соответствует всем 3 требованиям (что невозможно imo), но оно составило ту же функциональность, что и я.

В конце концов я использовал один класс, как предложил Марк в комментариях. Но тогда у меня был общий класс, вложенный внутри не общего класса, чтобы действовать для общей функциональности.

public static class Class 
{ 
    public static void ClassMethod() 
    { 
     SharedMethod<object>(); 
    } 



    static void SharedMethod<T>() 
    { 
     //---- 
    } 



    public static void GenericClassMethod<T>() 
    { 
     return GenericClass<T>.SharedMethod(); 
    } 

    static class GenericClass<T> 
    { 
     static void SharedMethod() 
     { 
      //available here since private members of outer class is visible to nested class 
      SharedMethod<T>(); 
     } 
    } 
} 

Так что теперь, даже несмотря на то, что вызываемая сделать немного по-другому от того, как я хотел первоначально в этом вопросе, функционально оба равны.

-1

Объявлять классы как запечатанные - таким образом они не будут наследоваться.

Если вы изменили разрешение от частного до защищенного, то все, что в вашем приложении может увидеть метод, но будет невидимым для другого приложения, пытающегося использовать ваши методы.

Надеюсь, это поможет!

+0

Не помогает, так как общая функциональность по-прежнему должна быть 'public/internal' – nawfal

+2

Это просто неправильно. Ваш компилятор, вероятно, будет кричать на вас за то, что вы защитили членов в закрытом классе. Это не имеет смысла. Может быть, вы перепутали слова и хотели сказать что-то еще? – nvoigt

-1

Если вы можете использовать одноэлементный шаблон, вы можете иметь 2 класса, причем общий класс наследуется от стандартного. Также вы можете сохранить ваши статические методы, вот что это может выглядеть следующим образом:

internal class ClassA 
{ 
    private static ClassA _instance; 
    private static ClassA Instance 
    { 
     get 
     { 
      if (_instance == null) _instance = new ClassA(); 
      return _instance; 
     } 
    } 

    protected void sharedMethod<T>() { } 

    public static void ClassMethod() 
    { 
     Instance.sharedMethod<object>(); 
    } 
} 

public sealed class GenericClass<T> : ClassA 
{ 
    private static GenericClass<T> _instance; 
    private static GenericClass<T> Instance 
    { 
     get 
     { 
      if (_instance == null) _instance = new GenericClass<T>(); 
      return _instance; 
     } 
    } 

    public static void GenericClassMethod() 
    { 
     Instance.sharedMethod<T>(); 
    } 
} 
+0

что это означает 'ClassA' является наследуемым, нарушает правило 2 – nawfal

+0

yep забыл об этом ... Но если вы хотите, чтобы только 2 класса использовали один метод, есть только два способа сделать это: иметь третий, содержащий этот метод, но тогда метод будет открыт или наследуется от одного класса ... Кстати, вы можете сделать ClassA внутренним, он будет еще менее доступным, и я нахожу его более безопасным, чем опция внутреннего метода – ppetrov

+0

В этом случае мой первый подход в вопросе было проще. Btw, вы можете сделать свой общий класс запечатанным – nawfal

1

Сначала я думал, что вы не можете отвечать 3 правила, но потом я подумал об отражении, и я придумал то, что работает , но , что не следует использовать, если вы действительно не имеют какой-либо другой способ достижения того, что вам нужно

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

public static class ClassA 
{ 
    private static void sharedMethod<T>() { } 

    public static void ClassMethod() 
    { 
     sharedMethod<object>(); 
    } 
} 

public static class GenericClass<T> 
{ 
    static MethodInfo sharedMethodInfo; 

    static GenericClass() 
    { 
     MethodInfo mi = typeof(ClassA).GetMethod("sharedMethod", BindingFlags.NonPublic | BindingFlags.Static); 
     sharedMethodInfo = mi.MakeGenericMethod(new Type[] { typeof(T) }); 
    } 

    public static void GenericClassMethod() 
    { 
     sharedMethodInfo.Invoke(null, null); 
    } 
} 
Смежные вопросы