.Net, эквивалентный для Явы, напечатал Класс <>?

Я-.NET парень, таким образом позвольте мне сначала утверждать, что мое понимание нескольких Явских понятий - исправляет меня, если я неправ.

Явские Непатентованные средства поддерживают понятие ограниченные подстановочные знаки :

class GenericClass< ? extends IInterface> { ... }

... который подобен.NET где ограничение:

class GenericClass where T: IInterface { ... }

Ява Класс класс описывает тип и является примерно </ими> эквивалентный.NET Напечатать класс

So far, so good. But I can't find a close enough equivalence to the Java genericly typed Class where T is a bounded wildcard. This basically imposes a restriction on the types that the Class represents.

Позвольте мне дать пример на Яве.

String custSortclassName = GetClassName(); //only known at runtime, 
                                          //e.g. it can come from a config file
Class<? extends IExternalSort> customClass 
    = Class.forName("MyExternalSort")
        .asSubclass(IExternalSort.class);  //this checks for correctness

IExternalSort impl = customClass.newInstance(); //look ma', no casting!

Самое близкое я мог войти в.NET, является чем-то вроде этого:

String custSortclassName = GetClassName(); //only known at runtime, 
                                          //e.g. it can come from a config file

Assembly assy = GetAssembly();             //unimportant 

Type customClass = assy.GetType(custSortclassName);
if(!customClass.IsSubclassOf(typeof(IExternalSort))){
    throw new InvalidOperationException(...);
}
IExternalSort impl = (IExternalSort)Activator.CreateInstance(customClass);

Явская версия смотрит уборщик мне. Есть ли способ улучшить.NET копию?

15
@Aschratt I don' t видят, как это относится к моему вопросу. Эта уловка могла быть полезной, если вся информация о типе известна во время компиляции, но тип, MyExternalSort не известен до времени выполнения - это может быть осуществлено клиентом моей библиотеки сортировки и только определяется по имени.
добавлено автор Cristi Diaconescu, источник
@jalf я знаю о стирании типа, таким образом, I' m, конечно, не ожидание 1:1 отображение. I' m, просто надеясь на некоторое улучшение по сравнению с моим в настоящее время не так симпатичное внедрение.
добавлено автор Cristi Diaconescu, источник
@jalf я знаю о стирании типа, таким образом, I' m, конечно, не ожидание 1:1 отображение. I' m, просто надеясь на некоторое улучшение по сравнению с моим в настоящее время не так симпатичное внедрение.
добавлено автор Cristi Diaconescu, источник
Я don' t знают много о Явских непатентованных средствах, но я действительно знаю это they' ре осуществило по-другому (никакая поддержка JVM) и поддержка много вещей, которые не делают.NET непатентованные средства. Так don' t ожидают находить прямой "эквивалент" для всего
добавлено автор jalf, источник
Я don' t знают много о Явских непатентованных средствах, но я действительно знаю это they' ре осуществило по-другому (никакая поддержка JVM) и поддержка много вещей, которые не делают.NET непатентованные средства. Так don' t ожидают находить прямой "эквивалент" для всего
добавлено автор jalf, источник
Это может быть немного слишком легко, но wouldn' t это быть возможным просто добавить новый () ограничение к, где ограничение? Что-то как MyExternalSort : IExternalSort, где T: IExternalSort, новые() и затем, используют вар impl = новый T (); ? Лично я использовал бы шаблон "фабрика", чтобы создать случаи типы, осуществляющие тот же самый интерфейс в таких сценариях.
добавлено автор Carsten, источник
@Cristi Diaconescu: специализированный тип не должен быть известен на времени компиляции. Это просто должно соответствовать, ваше ограничение (унаследуйте IExternalSort, конструктору без параметров) на времени компиляции, таким образом, можно также обеспечить некоторый параметр как случай IExternalSort, когда вы не знаете it' s точный тип.
добавлено автор Carsten, источник
@Cristi Diaconescu: специализированный тип не должен быть известен на времени компиляции. Это просто должно соответствовать, ваше ограничение (унаследуйте IExternalSort, конструктору без параметров) на времени компиляции, таким образом, можно также обеспечить некоторый параметр как случай IExternalSort, когда вы не знаете it' s точный тип.
добавлено автор Carsten, источник

7 ответы

Using extension methods & a custom wrapper class for System.Type, you can get pretty close to the Java syntax.

NOTE: Type.IsSubclassOf cannot be used to test if a type implements an interface - see the linked documentation on MSDN. One can use Type.IsAssignableFrom instead - see the code below.

using System;

class Type
{
    readonly Type type;

    public Type(Type type)
    {
       //Check for the subtyping relation
        if (!typeof(T).IsAssignableFrom(type))
            throw new ArgumentException("The passed type must be a subtype of " + typeof(T).Name, "type");

        this.type = type;
    }

    public Type UnderlyingType
    {
        get { return this.type; }
    }
}

static class TypeExtensions
{
    public static Type AsSubclass(this System.Type type)
    {
        return new Type(type);
    }
}

// This class can be expanded if needed
static class TypeWrapperExtensions
{
    public static T CreateInstance(this Type type)
    {
        return (T)Activator.CreateInstance(type.UnderlyingType);
    }
}

Использование дальнейшего совершенствования соединяет различие

(Should only be used in production code after the performance has been evaluated. Could be improved by using a (concurrent!) cache dictionary ConcurrentDictionary)

Using Covariant type parameters, a feature introduced with C# 4.0, and an additional type interface IType, which Type implements, one could make things like the following possible:

// IExternalSortExtended is a fictional interface derived from IExternalSort
IType extendedSort = ...
IType externalSort = extendedSort;//No casting here, too.

Можно было даже сделать:

using System;

interface IType
{
    Type UnderlyingType { get; }
}

static class TypeExtensions
{
    private class Type : IType
    {
        public Type UnderlyingType
        {
            get { return typeof(T); }
        }
    }

    public static IType AsSubclass(this System.Type type)
    {
        return (IType)Activator.CreateInstance(
           typeof(Type<>).MakeGenericType(type)
        );
    }
}

static class TypeWrapperExtensions
{
    public static T CreateInstance(this IType type)
    {
        return (T)Activator.CreateInstance(type.UnderlyingType);
    }
}

Так, чтобы можно было (явно) бросить между несвязанными интерфейсами InterfaceA и InterfaceB как:

var x = typeof(ConcreteAB).AsSubclass();
var y = (IType)x;

но такие поражения цель осуществления.

2
добавлено

Using extension methods & a custom wrapper class for System.Type, you can get pretty close to the Java syntax.

NOTE: Type.IsSubclassOf cannot be used to test if a type implements an interface - see the linked documentation on MSDN. One can use Type.IsAssignableFrom instead - see the code below.

using System;

class Type
{
    readonly Type type;

    public Type(Type type)
    {
       //Check for the subtyping relation
        if (!typeof(T).IsAssignableFrom(type))
            throw new ArgumentException("The passed type must be a subtype of " + typeof(T).Name, "type");

        this.type = type;
    }

    public Type UnderlyingType
    {
        get { return this.type; }
    }
}

static class TypeExtensions
{
    public static Type AsSubclass(this System.Type type)
    {
        return new Type(type);
    }
}

// This class can be expanded if needed
static class TypeWrapperExtensions
{
    public static T CreateInstance(this Type type)
    {
        return (T)Activator.CreateInstance(type.UnderlyingType);
    }
}

Использование дальнейшего совершенствования соединяет различие

(Should only be used in production code after the performance has been evaluated. Could be improved by using a (concurrent!) cache dictionary ConcurrentDictionary)

Using Covariant type parameters, a feature introduced with C# 4.0, and an additional type interface IType, which Type implements, one could make things like the following possible:

// IExternalSortExtended is a fictional interface derived from IExternalSort
IType extendedSort = ...
IType externalSort = extendedSort;//No casting here, too.

Можно было даже сделать:

using System;

interface IType
{
    Type UnderlyingType { get; }
}

static class TypeExtensions
{
    private class Type : IType
    {
        public Type UnderlyingType
        {
            get { return typeof(T); }
        }
    }

    public static IType AsSubclass(this System.Type type)
    {
        return (IType)Activator.CreateInstance(
           typeof(Type<>).MakeGenericType(type)
        );
    }
}

static class TypeWrapperExtensions
{
    public static T CreateInstance(this IType type)
    {
        return (T)Activator.CreateInstance(type.UnderlyingType);
    }
}

Так, чтобы можно было (явно) бросить между несвязанными интерфейсами InterfaceA и InterfaceB как:

var x = typeof(ConcreteAB).AsSubclass();
var y = (IType)x;

но такие поражения цель осуществления.

2
добавлено

Непатентованные средства C# - различие места декларации, различие параметра типа фиксируется.

Java is use-site variance, so once we have a declaration List, we can use it 3 ways

List          //invariant, read/write
List<+Number>         //covariant, read only
List<-NUmber>         //contravariant, write only

Есть за и против к обоим подходам. Подход места использования, по-видимому, более силен, хотя он получил репутацию, как являющуюся слишком трудным программистам. Я думаю, что на самом деле довольно легко схватить

List integers = ...;
List<+Number> numbers = integers; //covariant

К сожалению, Ява изобрела абсолютно отвратительный синтаксис,

List<? extends Number>   // i.e. List<+Number>

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

Now, in the declaration-site camp, how do we achieve 3 variances on the same class? By having more types - a ReadOnlyList, a WriteOnlyList, and a List extending both. This is not too bad, and one might say it's a better design. But it may become ugly if there are more type parameters. And if the designer of a class did not anticipate it being used variantly, the users of the class have no way to use it variantly.

1
добавлено
Я думаю, что теперь понимаю то, что ваш ответ о - хотя it' s более связанный с этот (более новый) вопрос мой. Возможно, можно смотреть.
добавлено автор Cristi Diaconescu, источник

Непатентованные средства C# - различие места декларации, различие параметра типа фиксируется.

Java is use-site variance, so once we have a declaration List, we can use it 3 ways

List          //invariant, read/write
List<+Number>         //covariant, read only
List<-NUmber>         //contravariant, write only

Есть за и против к обоим подходам. Подход места использования, по-видимому, более силен, хотя он получил репутацию, как являющуюся слишком трудным программистам. Я думаю, что на самом деле довольно легко схватить

List integers = ...;
List<+Number> numbers = integers; //covariant

К сожалению, Ява изобрела абсолютно отвратительный синтаксис,

List<? extends Number>   // i.e. List<+Number>

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

Now, in the declaration-site camp, how do we achieve 3 variances on the same class? By having more types - a ReadOnlyList, a WriteOnlyList, and a List extending both. This is not too bad, and one might say it's a better design. But it may become ugly if there are more type parameters. And if the designer of a class did not anticipate it being used variantly, the users of the class have no way to use it variantly.

1
добавлено
Я думаю, что теперь понимаю то, что ваш ответ о - хотя it' s более связанный с этот (более новый) вопрос мой. Возможно, можно смотреть.
добавлено автор Cristi Diaconescu, источник

Можно получить немного более симпатичную версию, используя "как" оператор:

String custSortclassName = GetClassName();
Assembly assy = GetAssembly();
Type customClass = assy.GetType(custSortclassName);

IExternalSort impl = Activator.CreateInstance(customClass) as IExternalSort;
if(impl==null) throw new InvalidOperationException(...);

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

0
добавлено
как оператор также выполняет бросок. Единственная разница, что она не бросает исключение, если бросок не был успешен. Этот doesn' t действительно облегчают.
добавлено автор Carsten, источник

Можно получить немного более симпатичную версию, используя "как" оператор:

String custSortclassName = GetClassName();
Assembly assy = GetAssembly();
Type customClass = assy.GetType(custSortclassName);

IExternalSort impl = Activator.CreateInstance(customClass) as IExternalSort;
if(impl==null) throw new InvalidOperationException(...);

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

0
добавлено
как оператор также выполняет бросок. Единственная разница, что она не бросает исключение, если бросок не был успешен. Этот doesn' t действительно облегчают.
добавлено автор Carsten, источник

Можно попытаться писать дополнительный метод как следующее:

 static class TypeExtension
    {
        public static I NewInstanceOf(this Type t) 
            where  I: class 
        {
            I instance = Activator.CreateInstance(t) as I;
            if (instance == null)
                throw new InvalidOperationException();
            return instance;
        }
    }

Который может тогда использоваться следующим образом:

String custSortclassName = GetClassName(); //only known at runtime, 
                                          //e.g. it can come from a config file

Assembly assy = GetAssembly();
Type customClass = assy.GetType(custSortclassName);            

IExternalSort impl = customClass.NewInstanceOf();
0
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

DotNetRuChat
DotNetRuChat
2 992 участник(ов)

Чат русскоязычного .NET сообщества http://dotnet.ru/ Вам могут быть интересны: @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @xamarin_russia, @microsoftstackjobs, @uwp_ru Флуд в @dotnettalks

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

pro.net
pro.net
710 участник(ов)

Обсуждение .NET Framework и всего, что с ним связано. Правила: не флудить не по теме, уважать ваших коллег и никакой рекламы (объявления о вакансиях можно согласовать с @AlexFails). Флудилка: @dotnettalks Участник @proDOT

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot

.NET Talks: Force Push Masters
.NET Talks: Force Push Masters
490 участник(ов)

Свободный чат .NET разработчиков. Правила: t.me/dotnettalks/56823 Вам могут быть интересны: @dotnetruchat, @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @dotnetgroup, @xamarin_russia, @microsoftstackjobs, @uwp_ru http://combot.org/chat/-1001128250813

.NET Chat Убежище
.NET Chat Убежище
246 участник(ов)

Чат .NET разработчиков под эгидой MSK/SPB .NET Community Group Вам могут быть интересны: @fsharp_chat, @dotnetruchat, @cilchat, @xamarin_russia, @microsoftstackjobs, @dotnetgroup Флуд в @dotnettalks

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async

.NET CIL Chat
.NET CIL Chat
54 участник(ов)

.NET CIL (aka IL aka MSIL)