考虑以下(大大简化)代码:
public T Function<T>() {
if (typeof(T) == typeof(string)) {
return (T) (object) "hello";
}
...
}
Run Code Online (Sandbox Code Playgroud)
首先施展到object那时是荒谬的T.但编译器无法知道先前的测试确保T类型string.
在C#中实现这种行为的最优雅,惯用的方式是什么(包括摆脱愚蠢typeof(T) == typeof(string),因为T is string不能使用)?
附录: .net中没有返回类型差异,因此你不能让函数重载来输入字符串(顺便说一下,这只是一个例子,但是多态性中关联结束重定义的一个原因,例如UML,可以不能用c#完成.显然,以下将是伟大的,但它不起作用:
public T Function<T>() {
...
}
public string Function<string>() {
return "hello";
}
Run Code Online (Sandbox Code Playgroud)
具体示例1:因为针对特定类型测试的通用函数不是通用的,所以有几次攻击,我将尝试提供更完整的示例.考虑Type-Square设计模式.以下是一个片段:
public class Entity {
Dictionary<PropertyType, object> properties;
public T GetTypedProperty<T>(PropertyType p) {
var val = properties[p];
if (typeof(T) == typeof(string) {
(T) (object) p.ToString(this); // magic going here …Run Code Online (Sandbox Code Playgroud) 在Scala中,可以使用泛型运算符(如+和 - )在泛型类型参数上定义方差.例如,List类型在标准库中是协变的.
class List[+A]
Run Code Online (Sandbox Code Playgroud)
因此,具有协变列表的函数可以像这样定义:
def foo[A](list : List[A])
Run Code Online (Sandbox Code Playgroud)
也可以使用通用边界模拟方差.所以我们也可以写这个
def foo[A](list : List[_:< A])
Run Code Online (Sandbox Code Playgroud)
当然这没有道理,因为list它已经是协变的.但是对于不协变的类型也可以采用相同的技巧.(像Stack).当然,也可以从协同的堆栈(聚合继承)创建新类型.
所以我的问题:
thx提前:)
C#规范声明参数类型不能同时具有协变性和逆变性.
这在创建协变或逆变接口时很明显,您可以分别使用"out"或"in"来修饰类型参数.没有选项允许同时("outin").
这种限制只是一种语言特定的约束,还是存在更深层次,更基本的理由,这种理由会使你不希望你的类型既有协变性又有逆变性?
编辑:
我的理解是阵列实际上既是协变的又是逆变的.
public class Pet{}
public class Cat : Pet{}
public class Siamese : Cat{}
Cat[] cats = new Cat[10];
Pet[] pets = new Pet[10];
Siamese[] siameseCats = new Siamese[10];
//Cat array is covariant
pets = cats;
//Cat array is also contravariant since it accepts conversions from wider types
cats = siameseCats;
Run Code Online (Sandbox Code Playgroud) 请参阅下面的编辑 使用R,我想过滤矩阵(基因表达数据)并仅保留具有高方差值的行(基因/探针).例如,我只想保留具有底部和顶部百分位数值的行(例如,低于20%且高于80%).我想将我的研究仅限于下游分析的高变异基因.R中有基因过滤的常用方法吗?
我的矩阵有18个样本(列)和47000个探针(行),其值为log2变换和标准化.我知道该quantile()功能可以识别每个样品列中的20%和80%截止值.我无法弄清楚如何为整个矩阵找到这些值,然后将原始矩阵子集化以删除所有"非变化"行.
示例矩阵的平均值为5.97,因此最后三行应该被删除,因为它们包含20%和80%截止值之间的值:
> m
sample1 sample2 sample3 sample4 sample5 sample6
ILMN_1762337 7.86 5.05 4.89 5.74 6.78 6.41
ILMN_2055271 5.72 4.29 4.64 5.00 6.30 8.02
ILMN_1736007 3.82 6.48 6.06 7.13 8.20 4.06
ILMN_2383229 6.34 4.34 6.12 6.83 4.82 5.57
ILMN_1806310 6.15 6.37 5.54 5.22 4.59 6.28
ILMN_1653355 7.01 4.73 6.62 6.27 4.77 6.12
ILMN_1705025 6.09 6.68 6.80 6.85 8.35 4.15
ILMN_1814316 5.77 5.17 5.94 6.51 7.12 7.20
ILMN_1814317 5.97 5.97 5.97 5.97 5.97 5.97
ILMN_1814318 5.97 5.97 …Run Code Online (Sandbox Code Playgroud) 方差有效性的精确规则有点模糊,不具体.我将列出关于什么使类型有效 - 协变的规则,并将一些查询和个人注释附加到每个规则.
A型是有效的协变,如果它是:
1)指针类型或非泛型类型.
指针和非泛型类型在C#中不是变体,除了数组和非泛型委托.通用类,结构和枚举是不变的.我在这儿吗?
2)数组类型T [],其中T是共同有效的.
所以这意味着如果T数组的元素类型T[]是协变的(引用或数组元素类型),那么数组是协变的,如果元素类型是不变的(值类型),那么数组类型是不变的.数组在C#中不能逆变.我在这儿吗?
3)泛型类型参数类型,如果它未被声明为逆变.
我们通常说泛型类型在参数类型上是变体,但是参数类型在它自己的变量上.这是另一种简短形式吗?例如,泛型类型T<out D>是协变的D(因此协变有效),因此我们可以说类型参数D是协变有效的.我对吗?
4)构造的类,结构,枚举,接口或委托类型X可能是协同有效的.为了确定它是否,我们以不同方式检查每个类型参数,具体取决于相应的类型参数是声明为covariant(out),contravariant(in)还是invariant(both).(当然,类和结构的泛型类型参数永远不会被声明为'out'或'in';它们将始终是不变的.)如果第i个类型参数被声明为covariant,那么Ti必须是covariantly有效的.如果它被宣布为逆变,那么Ti必须是有效的.如果它被声明为不变量,则Ti必须是不变的有效.
最后一条规则,从上到下,完全不明确.
我们是否在讨论泛型类型的所有in/out/invariant类型参数的方差?根据定义,泛型类型一次可以是一种类型参数的协变/逆变/不变量.为了协变或不变,在这种情况下,立即对它的所有类型参数都没有任何意义.这意味着什么?
向前进.为了确定泛型类型是否具有协变有效性,我们检查其类型参数(而不是类型参数).因此,如果相应的类型参数是covariant/contravariant/invariant,那么type参数分别是covariantly/contravariantly/invariantly有效...
我需要更深入地解释这条规则.
编辑:谢谢埃里克.非常感激!
我完全理解有效/无差异/不变的有效意义.如果类型绝对不是逆变的,那么类型是有效的,这意味着它可以是不变的.完全没问题!
对于第4条规则,您将遵循如何确定构造的泛型类型是否在协规中有效的过程,如规则中所定义.但是,如何确定声明为covariant(out)的类型参数是否具有协变有效性?
例如,在通用接口I {...}的闭合构造接口I {}中,不应该在通用接口声明中将类型参数声明为协变类型参数(out U)这一事实意味着类型参数对象是协变的吗?我认为应该.Cuz这就是协变的定义.object
另外,第二条规则:
2)数组类型T [],其中T是共同有效的.
什么是数组元素类型T是有效的协变意味着什么呢?你的意思是元素类型是值类型(在这种情况下是不变的)或引用类型(在这种情况下是协变)?
Cuz投影T→ T[]只有T参考类型才是变体.
我正在尝试创建一个函数来打印已定义数字列表的方差:
grades = [100, 100, 90, 40, 80, 100, 85, 70, 90, 65, 90, 85, 50.5]
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已尝试继续制作这三个功能:
def grades_sum(my_list):
total = 0
for grade in my_list:
total += grade
return total
def grades_average(my_list):
sum_of_grades = grades_sum(my_list)
average = sum_of_grades / len(my_list)
return average
def grades_variance(my_list, average):
variance = 0
for i in my_list:
variance += (average - my_list[i]) ** 2
return variance / len(my_list)
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试执行代码时,它会在以下行中给出以下错误:
Line: variance += (average - my_list[i]) ** 2
Error: list index out of range
Run Code Online (Sandbox Code Playgroud)
抱歉,如果我目前的Python知识有限,但我仍在学习 …
我需要有关泛型和委托方差的更多信息.以下代码段无法编译:
错误CS1961无效方差:类型参数'TIn'必须在'Test.F(Func)'上协变有效.'TIn'是逆变的.
public interface Test<in TIn, out TOut>
{
TOut F (Func<TIn, TOut> transform);
}
Run Code Online (Sandbox Code Playgroud)
.net Func定义如下:
public delegate TResult Func<in T, out TResult> (T arg);
Run Code Online (Sandbox Code Playgroud)
为什么编译器抱怨TIn逆变和TOut- 协变而Func期望完全相同的方差?
编辑
对我来说主要的限制是我希望我的Test界面将TOut作为协变,以便使用它:
public Test<SomeClass, ISomeInterface> GetSomething ()
{
return new TestClass<SomeClass, AnotherClass> ();
}
Run Code Online (Sandbox Code Playgroud)
鉴于此public class AnotherClass : ISomeInterface.
所以我有一个委托定义为:
public delegate void MyDelegate<T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)
Resharper建议我应该T如下逆变:
public delegate void MyDelegate<in T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)
现在,我很难理解这有什么用处?我知道它阻止我制作T一个返回类型,但T除此之外,通过制作逆变会得到什么有用的约束?也就是说,当需要将委托与实例一起使用时,我可以创建哪些实例
public delegate void MyDelegate<T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)
我无法创造
public delegate void MyDelegate<in T>(T myParameter);
Run Code Online (Sandbox Code Playgroud) 我正在开发一个需要获得图像方差的项目.目前我正采取两种方法(两种方法都有效,但速度很慢):
这是使用numpy的代码,varianceMatrix是输出
varianceMatrix = np.zeros(im.shape,np.uint8)
w = 1 # the radius of pixels neighbors
ny = len(im)
nx = len(im[0])
for i in range(w,nx-w):
for j in range(w,ny-w):
sampleframe = im[j-w:j+w, i-w:i+w]
variance = np.var(sampleframe)
varianceMatrix[j][i] = int(variance)
return varianceMatrix
Run Code Online (Sandbox Code Playgroud)
这是scipy功能:
from scipy import ndimage
varianceMatrix = ndimage.generic_filter(im, np.var, size = 3)
Run Code Online (Sandbox Code Playgroud)
scipy功能更快,但不是那么多.我正在寻找一种更好的替代方案来计算方差.
有任何想法吗???
我不明白我应该如何提出这个问题所以我使用这种方法.
我有一个纬度 - 经度数据集.下面张贴的图片是我想要制作的图片.这是我的数据集:
Latitude Longitude
21.06941667 71.07952778
21.06941667 71.07952778
21.06666667 71.08158333
21.07186111 71.08688889
21.08625 71.07083333
21.08719444 71.07286111
21.08580556 71.07686111
21.07894444 71.08225
....
Run Code Online (Sandbox Code Playgroud)

我使用geom_path()来查找路径.现在,如图所示.我已经突出了我想要做的路径周围的白色差异.这就是我计算方差的方法:
var.latitude <- var(Data$Latitude)
var.longitude <- var(Data$Longitude)
Run Code Online (Sandbox Code Playgroud)
我使用geom_errorbar()标记了点的方差:
geom_errorbar(aes(x=Latitude,y=Longitude, ymin=Longitude-var.longitude, ymax=Longitude+var.longitude),width=0.001)+
geom_errorbarh(aes(xmin=Latitude-var.latitude,xmax=Latitude+var.latitude),height=0.001)
Run Code Online (Sandbox Code Playgroud)
谁能告诉我如何突出白色区域?