General question ... Calling a static method from a common class

I have a general class:

public class MyList<LinkedItem> : List<LinkedItem> where LinkedItem : MyItem, new()
{
}

From this general class, I would like to access the static function from the LinkedItem class, which is a descendant of the MyItem class. (this way without instantiating LinkedItem).

Is it possible?

Thank,

Eric

+3
source share
6 answers

No, this is not possible directly from the type parameter, because you cannot call static methods on type type parameters (C # Lang Spec section 4.5).

A type parameter cannot be used in member access (§7.5.4) or type name (§3.8) to identify a static member or nested type.

, , . , , .

factory/, .

class MyItem : MyItem {
  static void TheFunction() { ... }
}

public class MyList<LinkedItem> : List<LinkedItem> where LinkedItem : MyItem, new()
{
  public MyList(Action theStaticFunction) {
    ...
  }
}

new MyList<MyItem>(MyItem.TheFunction);
+2

. , # API memebers.

, , :)

public class MyList<LinkedItem> : List<LinkedItem> 
                                      where LinkedItem : MyItem, new()
{
    public int CallStaticMethod()
    {
        // Getting a static method named "M" from runtime type of LinkedItem 
        var methodInfo = typeof(LinkedItem)
                      .GetMethod("M", BindingFlags.Static | BindingFlags.Public);

        // Invoking the static method, if the actual method will expect arguments
        // they'll be passed in the array instead of empty array
        return (int) methodInfo.Invoke(null, new object[0]);
    }

}

public class MyItem
{
}

class MyItemImpl : MyItem
{
    public MyItemImpl()
    {
    }

    public static int M()
    {
        return 100;
    }
}

, , 100:

public void Test()
{
    Console.WriteLine(new MyList<MyItemImpl>().CallStaticMethod());
}
+2

, , , MethodInfo typeof(T).GetMethod("Foo", BindingFlags.Public | BindingFlags.Static), Invoke .

, ConstructorInfo, MethodInfo, factory, . . , , , , , .

+2

. LinkedItem, , .

, :

public class ILinkedItemFactory<T>
{
    void YourMethodGoesHere();
}

public class MyList<LinkedItem, Factory> : List<LinkedItem>
    where Factory : ILinkedItemFactory<LinkedItem>
    where LinkedItem : MyItem, new()
{
    public MyList(Factory factory)
    {
        factory.YourMethodGoesHere();
    }
}
0

. , , , , LinkedItem , . . , .

DoSomething true. , ( , ).

public class MyList<LinkedItem> : List<LinkedItem>
{
    public bool DoSomething()
    {
        Type t = typeof(LinkedItem);
        object o = new Object();
        var result = t.InvokeMember("ReferenceEquals",
            BindingFlags.InvokeMethod |
            BindingFlags.Public |
            BindingFlags.Static,
            null,
            null, new[] { o, o });

        return (result as bool?).Value;
    }
}

// call it like this:
MyList<string> ml = new MyList<string>();
bool value = ml.DoSomething();   // true

PS: , , , ; -)

0

This is entirely possible, although not directly in the way you state, apart from thoughts. You would like to implement the non-static access method in the base class and override it in each specific inheritance class.

public class MyItem
{
    public static void DoSomeStaticStuff() { //DoSomeStaticStuff for MyItem }
    public virtual void AccessSomeStaticStuff() { MyItem.DoSomeStaticStuff(); }
}

public class SomeItem : MyItem
{
    public static void DoSomeStaticStuff() { //DoSomeStaticStuff for SomeItem }
    public override void AccessSomeStaticStuff() { SomeItem.DoSomeStaticStuff(); }
}

Then, in your class, which has a limitation, where T: MyItem, you simply call T.AccessSomeStaticStuff ();

0
source

Source: https://habr.com/ru/post/1759928/


All Articles