返回首页

我有一个泛型的小问题。
我想我已经知道答案,如果是这样的话,我选了摄影课。但我希望你们中的一些可以证明我错了{S0的}

我有一些通用接口和一些通用类实现。
问题是我需要的属性,属性不能处理泛型!
所以我不知道它的方式; TGT;是我的接口和类。相反,我有我的Interfacelt TGT从非泛型接口派生...不幸的是,非这种通用滑行通过我的类结构像一个非一般的蛇!
我已经取得了良好的工作类,用我的泛型接口和无属性,他们也可用。因此下降泛型产品总数是没有其他选择。
有一种方式,但转换BaseInterface;以1 DerivedInterfacelt的TGT;?这是当你还可以在运行时只知道T呢?
类似DerivedInterfacelt; myVar.GetType()GT

在傍晚,我的问题可能有点神秘,因此,如果我不够清晰,不要犹豫,问{S0的}
谢谢!

后年编辑编辑:
真的非常接近我的代码再重新再重新考虑后,我得出的结论,我的设计是捣毁(是的,即使我犯错误{S2的})!我不需要投IDerivedlt; intgt;到IDerivedlt; Objectgt;不过,我仍想知道如果它是可能的。

编辑:
到SAKryukov一个非常详细的答案!它真正的帮助! {S0的}
后有一个良好的夜间睡眠和阅读的SAKryukovs回答,我现在可以把我的问题,更好的话,虽然比去年晚。所以,这里又来了。
在下面的代码片断,最接近我自己的情况下,我必须转换一个Somethinglt; intgt;到Somethinglt; Objectgt;我看到它的方式是,int是一个对象,所以这种转换应该没有问题。错了!
作为SAKryukov把它(和他应该纠正我,如果我错了),这是因为Somethinglt; intgt;是类型Somethinglt; intgt的;(而不是东西,然后一个int或一个通用的东西)。 int对象Somethinglt的继承; intgt;即使不继承从Somethinglt; Objectgt的。


class Program

{

	static void Main(string[] args)

	{

		DerivedSomething thing = new DerivedSomething();

		if (CheckMustStop<int>(thing))

		{

			Console.WriteLine("Stop!");

		}

		else { Console.WriteLine("Don't stop!"); }

		Console.ReadKey();

	}

 

	static bool CheckMustStop<t>(Something<t> thing)

	{

		// This is where stuff gets nasty!

		// An int is an Object, but casting will not work!

                // Mind you that I know T is an int. In my own code I do not know this.

		Something<Object> tempThing = (Something<Object>)thing;

		return tempThing.MustStop;

	}

}

 

public class DerivedSomething : Something<int>

{

	public void DoSomething(int item)

	{

		// Do stuff here, <t> is important for item.

	}

		public bool MustStop

	{

		// <t> does not matter!

		get { return true; }

	}

}

 

public interface Something<t>

{

	void DoSomething(T item);

	bool MustStop { get; }

}

正如你所看到的不要紧类型T的例子。因为不管哪种类型T是它总是有一个不关心T的类型,这使我相信,Somethinglt MustStop物业; TGT;实际需要非通用基本接口,能够如果Somethinglt检查; TGT;必须停止任何类型:如本{C}这将创建新的问题,如只有自身可用时,它有一个非泛型的DoSomething方法和事实,我需要一个我几乎所有的通用接口的非泛型基接口。这真的会弄乱代码{S0的}

我希望,这进一步明确了我的问题。任何帮助是极大的赞赏{S0的}

回答

评论会员:游客 时间:2012/02/06
SAKryukov:很有趣的问题,即使是不太正确的答案是:当然你也可以从非泛型转换为普通。buthellip;让我们尝试理清头绪。我会尝试区分显得微妙,通常可以忽略的一些东西,但异国情调的情况下,你想是重要的。首先,BaseInterface一个DerivedInterfacelt;TGT;类型,你从来没有类型转换。想想看:你总是转换对象下一步。型铸造在这个意义上,你所谈论的是从来没有的转换。它不会移动任何地方的任何数据。它只是允许治疗作为另一种类型的类型声明的变量的值。一个特定的情况下铸造的关系为基础/派生的类型的变量:codeprelang="cs"spanclass="code-keyword"class/spanBase{spanclass="code-comment"/*/spanspanclass="code-comment"...*//span}spanclass="code-keyword"class/spanDerived:Base{spanclass="code-comment"/*/spanspanclass="code-comment"...*//span}Baseb=spanclass="code-keyword"new/spanDerived(spanclass="code-comment"/*/spanspanclass="code-comment"...*//span);Derivedd=(Derived)b;/pre/code不要紧,类或接口。唯一的A类或结构需要有一个实例来证明的情况下。(重要!注意结构也可以实现接口mdash;不是很​​出名的事实)请注意,这个演员是唯一可能的,因为B有一个运行时类型,这实际上是派生。你只能蒙上了一些编译时类型的变量,实际运行时类型或基地之一。最后,意识到这一点。泛型类型,即使确实存在,不仅在编译的时候,而且在运行时,它可以通过反射,泛型类型的对象中不存在。就其性质而言,所有的对象都是一些完全实例化的类型。你可以有一个System.Collections.Generic.Listlt对象;stringgt;,从来没有泛型List类型。问题很简单:{体C3}上面显示的抽象方法的主要好处是有一些不取决于操作的具体类型由IDerived接口抽象类代表算术算法的实施。这些方法都没有显示,他们可以包括操作数,搜索,排序(需要通用的约束,允许比较运算符)和更大量的集装箱。数字具体操作推迟到类实例化泛型类型。这个问题是数值类型,特别是困难多是泛型参数约束是类或(更容易)接口。我能理解,你有"通用"的问题,设计你的代码。好吧,我明白了,这是自然的,即使我真的不明白你的问题。据了解,可能需要一些示例代码。不过,我希望更好地了解泛型和面向对象相结合,可以帮助您有您的问题,重新审视和改善的事情。我也希望我的简单示例代码,可以给你一些想法。祝你好运,mdash;的SA:SAKryukov:按照要求,我回答问题的编辑版本是一个单独的答案。这个问题确实是从原来的问题完全不同。{S0的}所有的问题是滥用的非泛型方法,泛型接口。这里是如何固定的版本的代码看起来可能(而且它会奏效,当然):{的C4}我也改名东西ISomething满足(好)接口微软的命名约定。有一定的混乱,因为事实上,你错过一个重要的一步,这部分违背了泛型接口的目的。为了使继承链真正实用的,你需要做的是=GT通用(可能是抽象)类的执行方法不可知的泛型参数=GT;全面实施类mdash;使用显示在我以前的想法是这样的:通用接口回答。长期的"阶级"可以取代"结构"。[编辑#1]这是惊人的:我只是做一个真正的"弗洛伊德滑"(imgsrc=http://www.orcode.com/img/ico/smiley_smile.gif])!在上面的段落,我想键入"微软(好)的命名惯例",但输入"混日子微软命名约定"!不,他们是真的很不错,不偷懒。我使用它们[编辑完#1][编辑#2]经过一番思考,我意识到,我可以看到上面的代码中的两个问题。我上面的解释,1)缺少的中间实现类实现非泛型接口的一部分,这样你不会重复执行泛型类型的具体实施,每年这些非泛型方法/属性。剩下的两个问题是:2)接口被设计为在运行时使用;删除从您的代码mdash所有接口,它会在相同的方式工作,为什么写?你应该使用类通过接口;3)使用隐式接口实现(通过"公共");但显式接口实现更清晰的我的问题(2)及(3)在使用所需的变化,但使用接口的修复是真的有理由在切实有利的方式,缺乏代码的重用,如果固定(你想要的模式是非常有用的,只有当你需要有多个像DerivedSomething类,但如果您尝试写更多的类,你会不重用看到,MustStop实施);因此,代码固定在一起会看起来像这样:我修复了代码重用的缺乏是通过附加的接口IAgnostic,是不可知的泛型参数的和额外的抽象的实施类IAgnostic的。修复被证明有两种不同的终端完全实现类,DerivedSomething和DerivedSomethingElse。现在它是真正的权利。[完编辑#2]现在,我给你甚至没有触及集体命名为"协变和逆变"根主题的决议。要真正了解这些问题,你真的需要学习这个主题。在C#中的实践,它主要是关于新功能与以前的版本相比,推出的C#V.4所以,尽量阅读和理解这一点:{A},imgsrc=http://www.orcode.com/img/ico/smiley_tongue.gif](你真的需要读它的所有部件,但它需要一些努力找到他们!在这个博客的导航确实需要改进),{A3的}imgsrc=http://www.orcode.com/img/ico/smiley_smile.gif只是给你的协方差/逆变问题失去了多少C#和NET的想法:{5233}协方差/逆变生效的问题起到还有一类,其他类的实例每次使用时和使用的类型是派生。因此,问题是关于阵列,通用容器和泛型委托。这超出了铸造我们在这里讨论的主题。mdash;SA
什穆埃尔臧
评论会员:游客 时间:2012/02/06
如果铸造的目的是使用派生类的成员,您可以使用{A5的}]